Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #12483 > unrolled thread

Why do class methods always need 'self' as the first parameter?

Started by"T. Goodchild" <tgoodchild@gmail.com>
First post2011-08-31 07:35 -0700
Last post2011-09-05 20:58 -0700
Articles 10 on this page of 30 — 19 participants

Back to article view | Back to comp.lang.python


Contents

  Why do class methods always need 'self' as the first parameter? "T. Goodchild" <tgoodchild@gmail.com> - 2011-08-31 07:35 -0700
    Re: Why do class methods always need 'self' as the first parameter? John Gordon <gordon@panix.com> - 2011-08-31 14:54 +0000
      Re: Why do class methods always need 'self' as the first parameter? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-09-01 02:06 +1000
        Re: Why do class methods always need 'self' as the first parameter? Grant Edwards <invalid@invalid.invalid> - 2011-08-31 16:20 +0000
    Re: Why do class methods always need 'self' as the first parameter? Emile van Sebille <emile@fenx.com> - 2011-08-31 08:01 -0700
    Re: Why do class methods always need 'self' as the first parameter? Neil Cerutti <neilc@norwich.edu> - 2011-08-31 15:05 +0000
    Re: Why do class methods always need 'self' as the first parameter? Javier Collado <javier.collado@gmail.com> - 2011-08-31 17:10 +0200
    Re: Why do class methods always need 'self' as the first parameter? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-09-01 01:41 +1000
      Re: Why do class methods always need 'self' as the first parameter? Chris Torek <nospam@torek.net> - 2011-08-31 20:15 +0000
        Re: Why do class methods always need 'self' as the first parameter? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-09-01 10:48 +1000
          Re: Why do class methods always need 'self' as the first parameter? Chris Angelico <rosuav@gmail.com> - 2011-09-01 11:47 +1000
          Re: Why do class methods always need 'self' as the first parameter? Eric Snow <ericsnowcurrently@gmail.com> - 2011-08-31 20:07 -0600
          Re: Why do class methods always need 'self' as the first parameter? Chris Torek <nospam@torek.net> - 2011-09-01 02:20 +0000
        Re: Why do class methods always need 'self' as the first parameter? Piet van Oostrum <piet@vanoostrum.org> - 2011-09-05 16:15 +0200
          Re: Why do class methods always need 'self' as the first parameter? Chris Torek <nospam@torek.net> - 2011-09-06 01:10 +0000
            Re: Why do class methods always need 'self' as the first parameter? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-09-06 14:31 +1000
    Re: Why do class methods always need 'self' as the first parameter? Terry Reedy <tjreedy@udel.edu> - 2011-08-31 12:30 -0400
    RE: Why do class methods always need 'self' as the first parameter? "Prasad, Ramit" <ramit.prasad@jpmorgan.com> - 2011-08-31 13:12 -0400
      Re: Why do class methods always need 'self' as the first parameter? Piet van Oostrum <piet@vanoostrum.org> - 2011-09-08 01:01 +0200
    Re: Why do class methods always need 'self' as the first parameter? Chris Rebert <clp2@rebertia.com> - 2011-08-31 11:31 -0700
    Re: Why do class methods always need 'self' as the first parameter? Ian Kelly <ian.g.kelly@gmail.com> - 2011-08-31 15:52 -0600
    Re: Why do class methods always need 'self' as the first parameter? Terry Reedy <tjreedy@udel.edu> - 2011-08-31 18:40 -0400
    Re: Why do class methods always need 'self' as the first parameter? UncleLaz <andrei.lisnic@gmail.com> - 2011-09-01 03:40 -0700
      Re: Why do class methods always need 'self' as the first parameter? Michiel Overtoom <motoom@xs4all.nl> - 2011-09-01 13:23 +0200
    Re: Why do class methods always need 'self' as the first parameter? John Roth <johnroth1@gmail.com> - 2011-09-01 05:45 -0700
      Re: Why do class methods always need 'self' as the first parameter? Ian Kelly <ian.g.kelly@gmail.com> - 2011-09-01 08:26 -0600
        Re: Why do class methods always need 'self' as the first parameter? John Roth <johnroth1@gmail.com> - 2011-09-02 10:51 -0700
          Re: Why do class methods always need 'self' as the first parameter? Ian Kelly <ian.g.kelly@gmail.com> - 2011-09-02 14:30 -0600
            Re: Why do class methods always need 'self' as the first parameter? John Roth <johnroth1@gmail.com> - 2011-09-02 15:30 -0700
    Re: Why do class methods always need 'self' as the first parameter? rantingrick <rantingrick@gmail.com> - 2011-09-05 20:58 -0700

Page 2 of 2 — ← Prev page 1 [2]


#12527

FromIan Kelly <ian.g.kelly@gmail.com>
Date2011-08-31 15:52 -0600
Message-ID<mailman.632.1314827599.27778.python-list@python.org>
In reply to#12483
On Wed, Aug 31, 2011 at 11:12 AM, Prasad, Ramit
<ramit.prasad@jpmorgan.com> wrote:
> It seems to me that if I add a function to the list of class attributes it will automatically wrap with "self" but adding it to the object directly will not wrap the function as a method. Can somebody explain why? I would have thought that any function added to an object would be a method (unless decorated as a class method).

Because things stored on the class are generally viewed as part of the
class definition, whereas things stored on an instance are generally
viewed as data -- a function stored on an object instance is usually
just meant to be a function.  Consider the following code:

class Sorter(object):
    def __init__(self, keyfunc):
        self.keyfunc = keyfunc
    def sort(self, item_list):
        item_list.sort(key=self.keyfunc)

sorter = Sorter(lambda x: x.id)
sorter.sort(some_list_of_items)

If adding keyfunc as an attribute to the object wrapped it up as a
method, it would break, since the function is not expecting a "self"
argument.

More technically, because descriptors are only invoked when they're
stored on the class.

> Hmm, or does the decoration just tell Python not to turn an object's function into a method? I.e. Is the decorator basically just the syntactic sugar for doing the above?

If you mean the staticmethod decorator, yes, it pretty much just wraps
the function as a "staticmethod" instance to prevent it from being
wrapped into an ordinary method when it's accessed.

Cheers,
Ian

[toc] | [prev] | [next] | [standalone]


#12531

FromTerry Reedy <tjreedy@udel.edu>
Date2011-08-31 18:40 -0400
Message-ID<mailman.635.1314830484.27778.python-list@python.org>
In reply to#12483
On 8/31/2011 1:12 PM, Prasad, Ramit wrote:
>> def double(obj): return 2*obj.value
>>
>> class C:
>>   def __init__(self, val):
 >>       self.value = val
>>
>> c = C(3)
 >> C.double = double
 >> c.doub = double
 >> # not c.double as that would mask access to C.double in c.double()
 >> print(double(c),
>> C.double(c), c.double(), c.doub(c))

Above is 3.2 code. To be exactly equivalent with 2.x, you need
class C(object):

> Sorry if I get some of the following terminology wrong, I get a bit
> confused on Python terms. I hope the following is still coherent. (Is
> there a dictionary of Python terminology?)

> Given the above example I get this
>>>> print c.double(c)
> TypeError: double() takes exactly 1 argument (2 given)

Right, because c.double() translates to C.double(c), and c.double(x)
translates to C.double(c,x), which is not valid.

>>>> print c.doub(c)
> 6
>
> It seems to me that if I add a function to the list of class
> attributes it will automatically wrap with "self"

When accessed via an instance of the class, the instance is 
automagically added as the first argument to be bound to the first 
parameter. The name 'self' is a convention, not a requirement.

> but adding it to
> the object directly will not wrap the function as a method. Can
> somebody explain why?

Someone else did. Not wrapping is normal, wrapping is a special case.

-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#12560

FromUncleLaz <andrei.lisnic@gmail.com>
Date2011-09-01 03:40 -0700
Message-ID<058cb764-2ba2-4b63-be4d-33307a9a81cc@g31g2000yqh.googlegroups.com>
In reply to#12483
On Aug 31, 5:35 pm, "T. Goodchild" <tgoodch...@gmail.com> wrote:
> I’m new to Python, and I love it.  The philosophy of the language (and
> of the community as a whole) is beautiful to me.
>
> But one of the things that bugs me is the requirement that all class
> methods have 'self' as their first parameter.  On a gut level, to me
> this seems to be at odds with Python’s dedication to simplicity.
>
> For example, consider Python’s indent-sensitive syntax.  Although
> other languages didn’t use indentation to specify scope, programmers
> always used indentation anyways.  Making indentation took a common
> practice, made it a rule, and the result was a significantly improved
> signal-to-noise ratio in the readability of Python code.
>
> So why is 'self' necessary on class methods?  It seems to me that the
> most common practice is that class methods *almost always* operate on
> the instance that called them.  It would make more sense to me if this
> was assumed by default, and for "static" methods (methods that are
> part of a class, but never associated with a specific instance) to be
> labelled instead.
>
> Just curious about the rationale behind this part of the language.

It's required to make distinction between objects inside the calss and
outside of it. Seems pretty logical to me.

[toc] | [prev] | [next] | [standalone]


#12561

FromMichiel Overtoom <motoom@xs4all.nl>
Date2011-09-01 13:23 +0200
Message-ID<mailman.655.1314876266.27778.python-list@python.org>
In reply to#12560
> On Aug 31, 5:35 pm, "T. Goodchild" <tgoodch...@gmail.com> wrote:


>> So why is 'self' necessary on class methods?
>> 
>> Just curious about the rationale behind this part of the language.

When instance variables are accessed with the 'self.varname' syntax, it is clear to the programmer that an instance variable is accessed, and not some global.  Other languages have weird syntax conventions like that you have to prepend all instance attributes with an '@', and in languages like C++ where there is not necessarily such a syntactic requirement, many programmers use ad-hoc constructs like '_varname' or 'm_varname' to make the distinction clear.


>> It seems to me that the
>> most common practice is that class methods *almost always* operate on
>> the instance that called them.  It would make more sense to me if this
>> was assumed by default, and for "static" methods (methods that are
>> part of a class, but never associated with a specific instance) to be
>> labelled instead.

Yes, you have a point there. My personal preference would be to optimize for the most common case, while exceptions to the norm are still possible, but perhaps a bit more verbose.

Greetings

-- 
"Learn to value yourself, which means: fight for your happiness."  - Ayn Rand      

[toc] | [prev] | [next] | [standalone]


#12562

FromJohn Roth <johnroth1@gmail.com>
Date2011-09-01 05:45 -0700
Message-ID<42e335a7-b872-4229-ae02-13d61b7fab35@w22g2000prj.googlegroups.com>
In reply to#12483
On Aug 31, 8:35 am, "T. Goodchild" <tgoodch...@gmail.com> wrote:
> I’m new to Python, and I love it.  The philosophy of the language (and
> of the community as a whole) is beautiful to me.
>
> But one of the things that bugs me is the requirement that all class
> methods have 'self' as their first parameter.  On a gut level, to me
> this seems to be at odds with Python’s dedication to simplicity.
>
> For example, consider Python’s indent-sensitive syntax.  Although
> other languages didn’t use indentation to specify scope, programmers
> always used indentation anyways.  Making indentation took a common
> practice, made it a rule, and the result was a significantly improved
> signal-to-noise ratio in the readability of Python code.
>
> So why is 'self' necessary on class methods?  It seems to me that the
> most common practice is that class methods *almost always* operate on
> the instance that called them.  It would make more sense to me if this
> was assumed by default, and for "static" methods (methods that are
> part of a class, but never associated with a specific instance) to be
> labelled instead.
>
> Just curious about the rationale behind this part of the language.

I personally consider this to be a wart. Some time ago I did an
implementation analysis. The gist is that, if self and cls were made
special variables that returned the current instance and class
respectively, then the compiler could determine whether a function was
an instance or class method. If it then marked the code object
appropriately you could get rid of all of the wrappers and the
attendant run-time overhead.

I've never published the analysis because that train has already left
the shed. The earliest it could be considered would be 4.0, which
isn't even on the horizon.

John Roth

[toc] | [prev] | [next] | [standalone]


#12566

FromIan Kelly <ian.g.kelly@gmail.com>
Date2011-09-01 08:26 -0600
Message-ID<mailman.658.1314887244.27778.python-list@python.org>
In reply to#12562
On Thu, Sep 1, 2011 at 6:45 AM, John Roth <johnroth1@gmail.com> wrote:
> I personally consider this to be a wart. Some time ago I did an
> implementation analysis. The gist is that, if self and cls were made
> special variables that returned the current instance and class
> respectively, then the compiler could determine whether a function was
> an instance or class method. If it then marked the code object
> appropriately you could get rid of all of the wrappers and the
> attendant run-time overhead.

I don't see how you could get rid of the wrappers.  Methods would
still need to be bound, somehow, so that code like this will work:

methods = {}
for obj in objs:
    if obj.is_flagged:
        methods[obj.user_id] = obj.do_work
    else:
        methods[obj.user_id] = obj.do_other_work
# ...
methods[some_user_id]()

Without method wrappers, how does the interpreter figure out which
instance is bound to the method being called?

Cheers,
Ian

[toc] | [prev] | [next] | [standalone]


#12659

FromJohn Roth <johnroth1@gmail.com>
Date2011-09-02 10:51 -0700
Message-ID<975cd42a-00b0-4d2e-9f22-95b4021a7fbb@g32g2000pri.googlegroups.com>
In reply to#12566
On Sep 1, 8:26 am, Ian Kelly <ian.g.ke...@gmail.com> wrote:
> On Thu, Sep 1, 2011 at 6:45 AM, John Roth <johnro...@gmail.com> wrote:
> > I personally consider this to be a wart. Some time ago I did an
> > implementation analysis. The gist is that, if self and cls were made
> > special variables that returned the current instance and class
> > respectively, then the compiler could determine whether a function was
> > an instance or class method. If it then marked the code object
> > appropriately you could get rid of all of the wrappers and the
> > attendant run-time overhead.
>
> I don't see how you could get rid of the wrappers.  Methods would
> still need to be bound, somehow, so that code like this will work:
>
> methods = {}
> for obj in objs:
>     if obj.is_flagged:
>         methods[obj.user_id] = obj.do_work
>     else:
>         methods[obj.user_id] = obj.do_other_work
> # ...
> methods[some_user_id]()
>
> Without method wrappers, how does the interpreter figure out which
> instance is bound to the method being called?
>
> Cheers,
> Ian

Good question.

Currently the instance wrapper is created during method instantiation,
so the instance is obviously available at that point. There are two
rather obvious ways of remembering it. One is to use the invocation
stack, which has the instance. Another would be for the compiler to
create a local variable for the instance and possibly the class and
fill them in at instantiation time. Both of these require fixing the
names "self" and "cls" so the compiler knows what to do with them. The
first would require giving these two names their own bytecodes, the
second makes them simple local variables the same as the ones in the
method headers. The latter also allows them to be changed by the
method, which is probably not the world's best programming practice
although it's possible now.

John Roth

[toc] | [prev] | [next] | [standalone]


#12674

FromIan Kelly <ian.g.kelly@gmail.com>
Date2011-09-02 14:30 -0600
Message-ID<mailman.721.1314995446.27778.python-list@python.org>
In reply to#12659
On Fri, Sep 2, 2011 at 11:51 AM, John Roth <johnroth1@gmail.com> wrote:
>> I don't see how you could get rid of the wrappers.  Methods would
>> still need to be bound, somehow, so that code like this will work:
>>
>> methods = {}
>> for obj in objs:
>>     if obj.is_flagged:
>>         methods[obj.user_id] = obj.do_work
>>     else:
>>         methods[obj.user_id] = obj.do_other_work
>> # ...
>> methods[some_user_id]()
>>
>> Without method wrappers, how does the interpreter figure out which
>> instance is bound to the method being called?
>>
>> Cheers,
>> Ian
>
> Good question.
>
> Currently the instance wrapper is created during method instantiation,
> so the instance is obviously available at that point. There are two
> rather obvious ways of remembering it. One is to use the invocation
> stack, which has the instance. Another would be for the compiler to
> create a local variable for the instance and possibly the class and
> fill them in at instantiation time. Both of these require fixing the
> names "self" and "cls" so the compiler knows what to do with them. The
> first would require giving these two names their own bytecodes, the
> second makes them simple local variables the same as the ones in the
> method headers. The latter also allows them to be changed by the
> method, which is probably not the world's best programming practice
> although it's possible now.

That's not what I asked.  Both of those options are storing the
instance within a stack frame, once it's been called.  I'm asking how
you would remember the instance during the interval from the time when
the method
is accessed until when it has been called.

In the code above, the method is accessed just before it is stored in
the dictionary.  That is when the method wrapper is currently created,
and the instance is available.  It is not called until much later,
possibly not even within the same function.  How would you remember
the instance over that period without wrapping the function?

Cheers,
Ian

[toc] | [prev] | [next] | [standalone]


#12678

FromJohn Roth <johnroth1@gmail.com>
Date2011-09-02 15:30 -0700
Message-ID<d65b4506-f33d-4a79-87fd-4f3d74d89fa7@e34g2000prn.googlegroups.com>
In reply to#12674
On Sep 2, 2:30 pm, Ian Kelly <ian.g.ke...@gmail.com> wrote:
> On Fri, Sep 2, 2011 at 11:51 AM, John Roth <johnro...@gmail.com> wrote:
> >> I don't see how you could get rid of the wrappers.  Methods would
> >> still need to be bound, somehow, so that code like this will work:
>
> >> methods = {}
> >> for obj in objs:
> >>     if obj.is_flagged:
> >>         methods[obj.user_id] = obj.do_work
> >>     else:
> >>         methods[obj.user_id] = obj.do_other_work
> >> # ...
> >> methods[some_user_id]()
>
> >> Without method wrappers, how does the interpreter figure out which
> >> instance is bound to the method being called?
>
> >> Cheers,
> >> Ian
>
> > Good question.
>
> > Currently the instance wrapper is created during method instantiation,
> > so the instance is obviously available at that point. There are two
> > rather obvious ways of remembering it. One is to use the invocation
> > stack, which has the instance. Another would be for the compiler to
> > create a local variable for the instance and possibly the class and
> > fill them in at instantiation time. Both of these require fixing the
> > names "self" and "cls" so the compiler knows what to do with them. The
> > first would require giving these two names their own bytecodes, the
> > second makes them simple local variables the same as the ones in the
> > method headers. The latter also allows them to be changed by the
> > method, which is probably not the world's best programming practice
> > although it's possible now.
>
> That's not what I asked.  Both of those options are storing the
> instance within a stack frame, once it's been called.  I'm asking how
> you would remember the instance during the interval from the time when
> the method
> is accessed until when it has been called.
>
> In the code above, the method is accessed just before it is stored in
> the dictionary.  That is when the method wrapper is currently created,
> and the instance is available.  It is not called until much later,
> possibly not even within the same function.  How would you remember
> the instance over that period without wrapping the function?
>
> Cheers,
> Ian

I see what you're saying now - I didn't get your example the first
time. So the optimization of eliminating the instance wrapper is only
possible if it's retrieved via the instance and then called
immediately. That would seem to be a useful optimization if it was
possible - I wonder if PyPy is doing it since they've got that fancy
JIT, and it would seem that an immediate call after retrieving the
method is overwhelmingly more frequent than saving it for later.

I think it's still true that calling the underlying function object
through the instance wrapper requires remaking the parameter list,
which seems to be another piece of unnecessary overhead, unless
there's a fast path through the call machinery that treats the
instance specially.

It does, however, decouple the two issues so I can't claim the
optimization as a benefit. Drat.

John Roth

[toc] | [prev] | [next] | [standalone]


#12809

Fromrantingrick <rantingrick@gmail.com>
Date2011-09-05 20:58 -0700
Message-ID<90128a68-1a3c-433a-8cf8-efa3b130d7ea@hb5g2000vbb.googlegroups.com>
In reply to#12483
On Aug 31, 9:35 am, "T. Goodchild" <tgoodch...@gmail.com> wrote:
> I’m new to Python, and I love it.  The philosophy of the language (and
> of the community as a whole) is beautiful to me.

Welcome aboard mate!

> But one of the things that bugs me

Oh here we go! :-)

>  is the requirement that all class
> methods have 'self' as their first parameter.  On a gut level, to me
> this seems to be at odds with Python’s dedication to simplicity.

It will will seem odd at first. I too hated typing all those "selfs"
all the time. But believe me my new friend in no time those selfs will
roll of your fingers with great ease. You'll forget how much you hate
them and find much more to complain about.

Like for instance: I really lament the missing redundancy of Explicit
Lexical Scoping in python. For me global variables should have to be
qualified.

> For example, consider Python’s indent-sensitive syntax.  
> [...]
> and the result was a significantly improved
> signal-to-noise ratio in the readability of Python code.

Yes, forced indention is my favorite aspect of Python!

> So why is 'self' necessary on class methods?

It could be that Guido has a exaggerated self importance and just
liked the sound of all those selfs whist reading source code. However
i believe the real reason is really readability! It takes a while to
understand this aspect because the natural human response is to be
lazy (for instance i could have used "used to" in the previous
sentence if i was slothful). We are all inherently lazy beings who
need structure to keep us from spiraling out of control into the abyss
of selfishness.

GvR: Computer Scientist and Behavioral psychologist.

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | comp.lang.python


csiph-web