views:

232

answers:

6

I'm teaching myself Python and I see the following in Dive into Python section 5.3:

By convention, the first argument of any Python class method (the reference to the current instance) is called self. This argument fills the role of the reserved word this in C++ or Java, but self is not a reserved word in Python, merely a naming convention. Nonetheless, please don't call it anything but self; this is a very strong convention.

Considering that self is not a Python keyword, I'm guessing that it can sometimes be useful to use something else. Are there any such cases? If not, why is it not a keyword?

+8  A: 

No, unless you want to confuse every other programmer that looks at your code after you write it. self is not a keyword because it is an identifier. It could have been a keyword and the fact that it isn't one was a design decision.

Andrew Hare
If you're using `@classmethod`, however, the first argument isn't `self`, it's often `cls`.
S.Lott
That is true but that is simply another convention. I should have been more clear that the convention of using `self` applies to instance methods.
Andrew Hare
+1  A: 

I think that the main reason self is used by convention rather than being a Python keyword is because it's simpler to have all methods/functions take arguments the same way rather than having to put together different argument forms for functions, class methods, instance methods, etc.

Note that if you have an actual class method (i.e. one defined using the classmethod decorator), the convention is to use "cls" instead of "self".

JAB
That would be because you're no longer referring to an object instance but a class. (i.e. two different things)
Michael Mior
@michaelmior: While your first sentence is correct, the second is technically incorrect. Classes are first-class objects in Python, and can be manipulated just as other object instances can.
JAB
(Not that it makes much of a difference for methods contained inside a class.)
JAB
A: 

Because it is a convention, not language syntax. There is a Python style guide that people who program in Python follow. This way libraries have a familiar look and feel. Python places a lot of emphasis on readability, and consistency is an important part of this.

Nick
+3  A: 

The only case of this I've seen is when you define a function outside of a class definition, and then assign it to the class, e.g.:

class Foo(object):
    def bar(self):
        # Do something with 'self'

def baz(inst):
    return inst.bar()

Foo.baz = baz

In this case, self is a little strange to use, because the function could be applied to many classes. Most often I've seen inst or cls used instead.

tghw
Weird, but in this case, seems reasonable not to use self.
Adriano Varoli Piazza
+5  A: 

As a side observation, note that Pilgrim is committing a common misuse of terms here: a class method is quite a different thing from an instance method, which is what he's talking about here. As wikipedia puts it, "a method is a subroutine that is exclusively associated either with a class (in which case it is called a class method or a static method) or with an object (in which case it is an instance method).". Python's built-ins include a staticmethod type, to make static methods, and a classmethod type, to make class methods, each generally used as a decorator; if you don't use either, a def in a class body makes an instance method. E.g.:

>>> class X(object):
...   def noclass(self): print self
...   @classmethod
...   def withclass(cls): print cls
... 
>>> x = X()
>>> x.noclass()
<__main__.X object at 0x698d0>
>>> x.withclass()
<class '__main__.X'>
>>>

As you see, the instance method noclass gets the instance as its argument, but the class method withclass gets the class instead.

So it would be extremely confusing and misleading to use self as the name of the first parameter of a class method: the convention in this case is instead to use cls, as in my example above. While this IS just a convention, there is no real good reason for violating it -- any more than there would be, say, for naming a variable number_of_cats if the purpose of the variable is counting dogs!-)

Alex Martelli
"...note that Pilgrim is committing a common misuse of terms here: a class method is...": well, it depends on how you listen to his phrase "any Python class method." Is it "Python-class method" or "Python class-method"? You're taking the latter interpretation. If he'd said, "the first argument of any method of a Python class's instance method", he would have been perfectly clear if somewhat verbose.
hughdbrown
@hughdbrown: Or he could have said "the first argument of any instance method", which would imply that the method is a method of a class without having to state it.
JAB
@cat, yup. @hughdbrown, even in the kindest interpretation, "any method of a Python class" at least _includes_ classmethods (who could argue that classmethods aren't methods of a class?!) so the sentence is still wrong. Mark is a friend and a colleague, and I love his work, but it's nevertheless clear that he (and my wife Anna, who was his tech editor for the book) had a small howler here!-)
Alex Martelli
+1  A: 

I once had some code like (and I apologize for lack of creativity in the example):

class Animal:
    def __init__(self, volume=1):
        self.volume = volume
        self.description = "Animal"

    def Sound(self):
        pass

    def GetADog(self, newvolume):
        class Dog(Animal):
            def Sound(this):
                return self.description + ": " + ("woof" * this.volume)
        return Dog(newvolume)

Then we have output like:

>>> a = Animal(3)
>>> d = a.GetADog(2)
>>> d.Sound()
'Animal: woofwoof'

I wasn't sure if self within the Dog class would shadow self within the Animal class, so I opted to make Dog's reference the word "this" instead. In my opinion and for that particular application, that was more clear to me.

Mark Rushakoff