Why must 'self' be used explicitly in method definitions and calls?

The idea was borrowed from Modula-3. It turns out to be very useful, for a variety of reasons.

First, it’s more obvious that you are using a method or instance attribute instead of a local variable. Reading self.x or self.meth() makes it absolutely clear that an instance variable or method is used even if you don’t know the class definition by heart. In C++, you can sort of tell by the lack of a local variable declaration (assuming globals are rare or easily recognizable) — but in Python, there are no local variable declarations, so you’d have to look up the class definition to be sure. Some C++ and Java coding standards call for instance attributes to have an m_ prefix, or for such attributes to be referenced through the special this variable, so this explicitness is still useful in those languages, too.

Second, it means that no special syntax is necessary if you want to explicitly reference or call the method from a particular class. In C++, if you want to use a method from a base class which is overridden in a derived class, you have to use the :: operator — in Python you can write baseclass.methodname(self, <argument list>). This is particularly useful for __init__ methods, and in general in cases where a derived class method wants to extend the base class method of the same name and thus has to call the base class method somehow.

Finally, for instance variables it solves a syntactic problem with assignment: since local variables in Python are (by definition!) those variables to which a value assigned in a function body (and that aren’t explicitly declared global), there has to be some way to tell the interpreter that an assignment was meant to assign to an instance variable instead of to a local variable, and it should preferably be syntactic (for efficiency reasons). C++ does this through declarations, but Python doesn’t have declarations and it would be a pity having to introduce them just for this purpose. Using the explicit self.var solves this nicely. Similarly, for using instance variables, having to write self.var means that references to unqualified names inside a method don’t have to search the instance’s directories. To put it another way, local variables and instance variables live in two different namespaces, and you need to tell Python which namespace to use.

CATEGORY: general

CATEGORY: design

 

Comment:

From Steven D'Aprano on c.l.py (http://groups.google.com/group/comp.lang.python/msg/c9a3a410c465e624)

Implicit self will never be used for Python, because it is redundant so
long as there is a need for explicit self, and there is a need for
explicit self because there are a number of basic, dare I say
*fundamental* programming techniques that require an explicit self.

For example, delegation.

class MyClass(Parent):
    def method(self, arg):
        Parent.method(self, arg)
        # what are you going to write? Parent.method(,arg) maybe?

Here's another fundamental technique that implicit self breaks.

class MyList(list):
    def __iadd__(self, other):
        # in-place addition
        other = transform(other) # do something to the argument
        super(MyList, self).__iadd__(other) # call the superclass
        # could be written .__class__.__iadd__(other)
        # BUT be aware the semantics are NOT the same!
        return self  # and return the suitably modified instance

You can't explicitly return the instance unless you have an explicit name
for it. (And if you are thinking of creating more magic syntax that
implicitly returns self, just don't bother.)

Even more fundamentally, any time you need to pass the instance to a
function, you need an explicit self. (Delegation is a special case of this.)

    def __str__(self):
        # I like semicolons and dislike square brackets.
        return ';'.join(self) 

Posted by Eduardo O Padoan (2006-11-18)

Comment:

All of this fails to explain why "self" has to mentioned in the method signature, and why it can't be a keyword like C++'s "this", providing access to the current instance. Why not quote the python Zen on this one and admit it was a design decision to be explicit?

Posted by Ralph (2006-11-25)

Comment:

I remember reading Guido saying that exlicity self helps to differenciate functions and methods. """ Having self be explicit is a good thing. It makes the code clear by removing ambiguity about how a variable resolves. It also makes the difference between functions and methods small. """ http://www.python.org/dev/peps/pep-3099/#core-language Some more arguments: http://zephyrfalcon.org/weblog/arch_d7_2003_07_12.html#e283 http://zephyrfalcon.org/weblog/arch_d7_2003_07_26.html#e298

Posted by Eduardo O Padoan (2006-11-25)

Comment:

Consider the following (admittedly contrived) case:

class Outer(object):
    """Class Outer."""

    def methodOuter(self_outer):
        """This method builds a class on the fly and returns it."""

        class Inner(object):
            """Class Inner."""

            def methodInner(self_inner):
                #Some code goes here.
                pass

        return Inner

If self were implicit you could never get your hands on self_outer inside methodInner. Explicit self allows you to do exactly that.

Posted by G. Rodrigues (2006-12-04)

Comment:

"If self were implicit you could never get your hands on self_outer inside methodInner. Explicit self allows you to do exactly that." Lots of blinders on around here. class Outer(object): def methodOuter(): """This method builds a class on the fly and returns it.""" self_outer = self class Inner(object): def methodInner(): print self_outer return Inner This should work to the extent that the code above works, yes?

Posted by Your implicit self (2007-04-05)

A Django site. rendered by a django application. hosted by webfaction.