[Tutor] question on self

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

[Tutor] question on self

Michael Lewis
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()?

--
Michael J. Lewis
 



_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] question on self

Steven D'Aprano-8
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
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] question on self

Steve Willoughby
On 11-Mar-12 20:03, Steven D'Aprano wrote:

> 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()?

Steven's notes about scoping rules are one reason.  Another is the
matter of object instance binding.  When you call a method, you're not
just calling a regular function.  You're calling a function bound to a
particular object, so by saying self.TakeTurns(), Python knows that the
object "self" is invoking that method, not some other instance of the
Play class.  That method then can access all of that specific object's
attributes as necessary.

--
Steve Willoughby / [hidden email]
"A ship in harbor is safe, but that is not what ships are built for."
PGP Fingerprint 4615 3CCE 0F29 AE6C 8FF4 CA01 73FE 997A 765D 696C
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] question on self

Alan Gauld
In reply to this post by Michael Lewis
On 12/03/12 02:02, Michael Lewis wrote:

> 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()?

The Steve's have given technical answers, its also stylistically
better because it removed ambiguity for the reader as well as
for Python.

Many corporate style guides advocate using this same style
when using C++ or Java to make it explicit when you are using
a class attribute rather than a local or global value/function.

It improves code clarity and therefore reduces potential bugs
and speeds up maintenance for a tiny loss in initial coding
productivity.

--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/

_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] question on self

Bill Allen-10
This little thread on the usage of self references when calling class instance methods and attributes was excellent, one of the best I have seen.

Thanks,
Bill Allen
Sent from my iPhone

On Mar 12, 2012, at 3:56, Alan Gauld <[hidden email]> wrote:

> On 12/03/12 02:02, Michael Lewis wrote:
>
>> 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()?
>
> The Steve's have given technical answers, its also stylistically
> better because it removed ambiguity for the reader as well as
> for Python.
>
> Many corporate style guides advocate using this same style
> when using C++ or Java to make it explicit when you are using
> a class attribute rather than a local or global value/function.
>
> It improves code clarity and therefore reduces potential bugs
> and speeds up maintenance for a tiny loss in initial coding
> productivity.
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
>
> _______________________________________________
> Tutor maillist  -  [hidden email]
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] question on self

wesley chun
i want to expand specifically on steve's response and note the big distinction that needs to be made for everyone is that this is primary the difference between calling a *function* and calling a *method* (which is a function that belongs to/defined for a class).

with that instance (self), that method is considered "bound," and Python automagically passes it in as the first argument to that method (self). if you wish to call an *unbound* method, you need to pass an instance on your own *and* reference it via its class, i.e., YourClass.TakeTurns(self) -- readability takes a blow there.

btw, if you want to make just a function call *and* that function doesn't have much to do with the class, then just define it as a function. a seldomly-used alternative is to make it a static method (using the @staticmethod decorator) -- this lets you define a method within a class but pretend it's like a function (where you don't need to use the instance [self]).

cheers,
--wesley
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"Core Python Programming", Prentice Hall, (c)2007,2001
"Python Fundamentals", Prentice Hall, (c)2009
    http://corepython.com

wesley.chun : wescpy-gmail.com : @wescpy/+wescpy
python training and technical consulting
cyberweb.consulting : silicon valley, ca
http://cyberwebconsulting.com

_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor