Methods

Because you already know about functions, you also know about methods in classes. Methods are just function objects created by def statements nested in a class statement’s body. From an abstract perspective, methods provide behavior for instance objects to inherit. From a programming perspective, methods work in exactly the same way as simple functions, with one crucial exception: a method’s first argument always receives the instance object that is the implied subject of the method call.

In other words, Python automatically maps instance method calls to a class’s method functions as follows. Method calls made through an instance, like this:

instance.method(args...)

are automatically translated to class method function calls of this form:

class.method(instance, args...)

where Python determines the class by locating the method name using the inheritance search procedure. In fact, both call forms are valid in Python.

Besides the normal inheritance of method attribute names, the special first argument is the only real magic behind method calls. In a class’s method, the first argument is usually called self by convention (technically, only its position is significant, not its name). This argument provides methods with a hook back to the instance that is the subject of the call—because classes generate many instance objects, they need to use this argument to manage data that varies per instance.

C++ programmers may recognize Python’s self argument as being similar to C++’s this pointer. In Python, though, self is always explicit in your code: methods must always go through self to fetch or change attributes of the instance being processed by the current method call. This explicit nature of self is by design—the presence of this name makes it obvious that you are using instance attribute names in your script, not names in the local or global scope.

Method Example

To clarify these concepts, let’s turn to an example. Suppose we define the following class:

class NextClass:                            # Define class
    def printer(self, text):                # Define method
        self.message = text                 # Change instance
        print(self.message)                 # Access instance

The name printer references a function object; because it’s assigned in the class statement’s scope, it becomes a class object attribute and is inherited by every instance made from the class. Normally, because methods like printer are designed to process instances, we call them through instances:

>>> x = NextClass()                         # Make instance
>>> x.printer('instance call')              # Call its method
instance call
>>> x.message                               # Instance changed
'instance call'

When we call the method by qualifying an instance like this, printer is first located by inheritance, and then its self argument is automatically assigned the instance object (x); the text argument gets the string passed at the call ('instance call'). Notice that because Python automatically passes the first argument to self for us, we only actually have to pass in one argument. Inside printer, the name self is used to access or set per-instance data because it refers back to the instance currently being processed.

As we’ve seen, though, methods may be called in one of two ways—through an instance, or through the class itself. For example, we can also call printer by going through the class name, provided we pass an instance to the self argument explicitly:

>>> NextClass.printer(x, 'class call')      # Direct class call
class call
>>> x.message                               # Instance changed again
'class call'

Calls routed through the instance and the class have the exact same effect, as long as we pass the same instance object ourselves in the class form. By default, in fact, you get an error message if you try to call a method without any instance:

>>> NextClass.printer('bad call')
TypeError: unbound method printer() must be called with NextClass instance...

Calling Superclass Constructors

Methods are normally called through instances. Calls to methods through a class, though, do show up in a variety of special roles. One common scenario involves the constructor method. The __init__ method, like all attributes, is looked up by inheritance. This means that at construction time, Python locates and calls just one __init__. If subclass constructors need to guarantee that superclass construction-time logic runs, too, they generally must call the superclass’s __init__ method explicitly through the class:

class Super:
    def __init__(self, x):
        ...default code...

class Sub(Super):
    def __init__(self, x, y):
        Super.__init__(self, x)             # Run superclass __init__
        ...custom code...                   # Do my init actions

I = Sub(1, 2)

This is one of the few contexts in which your code is likely to call an operator overloading method directly. Naturally, you should call the superclass constructor this way only if you really want it to run—without the call, the subclass replaces it completely. For a more realistic illustration of this technique in action, see the Manager class example in the prior chapter’s tutorial.[59]

Other Method Call Possibilities

This pattern of calling methods through a class is the general basis of extending—instead of completely replacing—inherited method behavior. It requires an explicit instance to be passed because all methods do by default. Technically, this is because methods are instance methods in the absence of any special code.

In Chapter 32, we’ll also meet a newer option added in Python 2.2, static methods, that allow you to code methods that do not expect instance objects in their first arguments. Such methods can act like simple instanceless functions, with names that are local to the classes in which they are coded, and may be used to manage class data. A related concept we’ll meet in the same chapter, the class method, receives a class when called instead of an instance and can be used to manage per-class data, and is implied in metaclasses.

These are both advanced and usually optional extensions, though. Normally, an instance must always be passed to a method—whether automatically when it is called through an instance, or manually when you call through a class.

Note

Per the sidebar What About super? in Chapter 28, Python also has a super built-in function that allows calling back to a superclass’s methods more generically, but we’ll defer its presentation until Chapter 32 due to its downsides and complexities. See the aforementioned sidebar for more details; this call has well-known tradeoffs in basic usage, and an esoteric advanced use case that requires universal deployment to be most effective. Because of these issues, this book prefers to call superclasses by explicit name instead of super as a policy; if you’re new to Python, I recommend the same approach for now, especially for your first pass over OOP. Learn the simple way now, so you can compare it to others later.



[59] On a related note, you can also code multiple __init__ methods within the same class, but only the last definition will be used; see Chapter 31 for more details on multiple method definitions.