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

Chris Torek nospam at torek.net
Wed Aug 31 22:15:44 CEST 2011


>In article <0dc26f12-2541-4d41-8678-4fa53f347acf at g9g2000yqb.googlegroups.com>
T. Goodchild asked, in part:
>>... One of the things that bugs me is the requirement that all class
>>methods have 'self' as their first parameter.

In article <4e5e5628$0$29977$c3e8da3$5496439d at news.astraweb.com>
Steven D'Aprano  <steve+comp.lang.python at pearwood.info> wrote:
[Comprehensive reply, noting that these are actually instance
methods, and that there are class and static methods as well]:

>Python does have class methods, which receive the class, not the instance,
>as the first parameter. These are usually written something like this:
>
>class K(object):
>    @classmethod
>    def spam(cls, args):
>        print cls  # always prints "class K", never the instance
>
>Just like self, the name cls is a convention only. Class methods are usually
>used for alternate constructors.
>
>There are also static methods, which don't receive any special first
>argument, plus any other sort of method you can invent, by creating
>descriptors... but that's getting into fairly advanced territory. ...
[rest snipped]

I am not sure whether T. Goodchild was asking any of the above or
perhaps also one other possible question: if an instance method
is going to receive an automatic first "self" parameter, why require
the programmer to write that parameter in the "def"?  For instance
we *could* have:

    class K(object):
        def meth1(arg1, arg2):
            self.arg1 = arg1 # self is "magically available"
            self.arg2 = arg2

        @classmethod
        def meth2(arg):
            use(cls) # cls is "magically available"

and so on.  This would work fine.  It just requires a bit of implicit
sneakiness in the compiler: an instance method magically creates
a local variable named "self" that binds to the invisible first
parameter, and a class method magically creates a local variable
named "cls" that binds to the invisible first parameter, and so
on.

Instead, we have a syntax where you, the programmer, write out the
name of the local variable that binds to the first parameter.  This
means the first parameter is visible.  Except, it is only visible
at the function definition -- when you have the instance and call
the instance or class method:

    black_knight = K()
    black_knight.meth1('a', 1)
    black_knight.meth2(2)

the first parameters (black_knight, and black_knight.__class__,
respectively) are magic, and invisible.

Thus, Python is using the "explicit is better than implicit" rule
in the definition, but not at the call site.  I have no problem with
this.  Sometimes I think implicit is better than explicit.  In this
case, there is no need to distinguish, at the calls to meth1() and
meth2(), as to whether they are "class" or "instance" methods.  At
the *calls* they would just be distractions.

At the *definitions*, they are not as "distraction-y" since it is
important to know, during the definition, whether you are operating
on an instance (meth1) or the class itself (meth2), or for that
matter on neither (static methods).  One could determine this from
the absence or presence of "@classmethod" or "@staticmethod", but
the minor redundancy in the "def" statement seems, well, minor.

Also, as a bonus, it lets you obfuscate the code by using a name
other than "self" or "cls". :-)
-- 
In-Real-Life: Chris Torek, Wind River Systems
Intel require I note that my opinions are not those of WRS or Intel
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W)  +1 801 277 2603
email: gmail (figure it out)      http://web.torek.net/torek/index.html



More information about the Python-list mailing list