[Tutor] question on self

Steven D'Aprano steve at pearwood.info
Mon Mar 12 04:03:55 CET 2012


On Sun, Mar 11, 2012 at 07:02:11PM -0700, Michael Lewis wrote:
> Why do I have to use "self.example" when calling a method inside a class?
> 
> For example:
> 
>     def Play(self):
>         '''find scores, reports winners'''
>         self.scores = []
>         for player in range(self.players):
>             print
>             print 'Player', player + 1
>             self.scores.append(self.TakeTurns())
> 
> I have another method called take turns (not shown for brevity purposes).
> When I want to call it, why can't I just call it like a function and use
> TakeTurns() instead of self.TakeTurns()?

When you call range() inside a method, as you do above, do you 
expect to get the global range() function, or the self.range() 
method (which likely doesn't exist)?

Same for len(), or any other built-in or global.

Similarly, how do you expect Python to distinguish between a persistent 
attribute, like self.scores, and a local variable, like player?

Since Python can't read your mind, one way or another you have to 
explicitly tell the compiler which of the two name resolution 
orders to use:

(1) The normal function scope rules:

    - local variables have priority over:
    - non-locals, which have priority over:
    - globals, which have priority over:
    - built-ins;

(2) or the attribute search rules, which is quite compilicated but a 
simplified version is:

    - instance attributes or methods
    - class attributes or methods
    - superclass attributes or method
    - computed attributes or methods using __getattr__

Python refuses to guess which one you want, since any guess is likely to 
be wrong 50% of the time. Instead, Python's design is to always use 
function scope rules, and if you want attributes or methods, you have to 
explicitly ask for them. This makes MUCH more sense than having to 
explicitly flag local variables!

Other languages made other choices. For instance, you might demand that 
the programmer declare all their variables up-front, and all their 
instance attributes. Then the compiler can tell at compile-time that 
range is a built-in, that player is a local variable, and that TakeTurns 
is an instance attribute. That's a legitimate choice, and some languages 
do it that way.

But having programmed in some of these other languages, give me Python's 
lack of declarations anytime!

Since all names (variables and attributes) in Python are generated at 
runtime, the compiler normally cannot tell what the scope of a name is 
until runtime (with a few exceptions).


-- 
Steven


More information about the Tutor mailing list