Next / Previous / Contents / Shipman's homepage

26.1. Old-style classes

Old-style classes are those declared without a parent class, or classes that inherit from an existing old-style class.

Here is an outline of the birth, life, and death of an old-style class and its instances.

26.1.1. Defining an old-style class

To define an old-style class C with no parent class, use this general form:

class C:
    ...class methods and variables...

To create a class that inherits from one or more parent classes P1, P2, …:

class C(P1, P2, ...):              
    ...class methods and variables...

As Python reads the definition of your class, it first creates a new, empty namespace called the class namespace. You can access the class namespace directly as an attribute named __dict__, a dictionary whose keys are the names in that namespace.

As Python reads each method or class variable in your class declaration, it adds the name of that method or variable to the class namespace.

26.1.2. Instantiation of an old-style class: The constructor, .__init__()

The creation of a new instance of a class happens when a running Python program encounters a call to that class, that is, the class name with a pair of parentheses after it, with zero or more arguments inside the parentheses.

Here is the general form:

C(a1, a2, ...)                

The instance creation (also called instantiation) is handled by the __init__() or constructor method.

  1. First Python creates the instance with an empty .__dict__ attribute that will contain the instance's values.

  2. Python then calls the constructor. The argument list for this call always has the special first argument self (the instance), followed by whatever arguments were used in the initial call. The constructor call is equivalent to this:

    C.__init__(self, a1, a2, ...)
    

  3. The constructor method then executes. Typically the constructor will set up new instance attributes by assignments of this form:

            self.name = expression
    

    When the constructor finishes executing, the instance is returned to the constructor's caller.

26.1.3. Attribute references in old-style classes

The names inside the instance are called attributes. (The methods are technically attributes—attributes that are of type function.) There are three operations on attributes: get, set, and delete.

  • To get an attribute means to retrieve its value. Python searches the instance's .__dict__ for the attribute's name; if that name is found, its value is returned. If the instance's .__dict__ does not have a binding for the given name, Python searches the class's .__dict__. If no value is found there, Python searches the namespaces of the ancestor classes (if any).

    >>> class C:
    ...     def __init__(self, x):
    ...         self.thingy = x
    ... 
    >>> c=C(42)
    >>> c.thingy
    42
    >>> c.__dict__['thingy']
    42
    

    When you call a method M of an instance I in an expression of the form “I.M(...)”, this is considered just another attribute “get” operation: the get operation I.M retrieves the method, and then that method is called using the arguments inside the “(...)”.

  • To set an attribute means to give it a value. If there is an existing attribute with the same name, its old value is discarded, and the attribute name is bound to the new value. The new value is stored in the instance's .__dict__.

    >>> c.thingy
    42
    >>> c.thingy = 58
    >>> c.thingy
    58
    >>> c.__dict__['thingy']
    58
    

  • You can delete an attribute from an instance using a del statement (see Section 22.3, “The del statement: Delete a name or part of a value”).

    >>> c.thingy
    58
    >>> del c.thingy
    >>> c.thingy
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: C instance has no attribute 'thingy'
    

In addition to ordinary attributes and methods, your class can accept references to names that do not exist in the instance or class namespace. You can define special methods that will be called when some statement tries to get, set, or delete an attribute that isn't found in the instance's .__dict__. See Section 26.3.14, “__getattr__(): Handle a reference to an unknown attribute”, Section 26.3.21, “__setattr__(): Intercept all attribute changes”, and Section 26.3.9, “__delattr__(): Delete an attribute”.

If all else fails—if an attribute is not found in the instance's namespace and the class does not provide a special method that handles the attribute reference—Python will raise an AttributeError exception.

26.1.4. Method calls in an old-style class

There are two different ways to call a method M of some class C:

  • Most calls are bound method calls of this form, where I is an instance of some class C:

    I.methodName(a1, a2, ...)
    

    The instance I replaces self as the first argument when setting up the arguments to be passed to the method.

  • The following form, called an unbound method call, is exactly equivalent to the above:

    C.methodName(i, a1, a2, ...)
    

Here is a demonstration of the equivalence of bound and unbound method calls.

>>> class C:
...     def __init__(self, x):
...         self.x = x
...     def show(self, y):
...         print "*** ({0},{1}) ***".format(self.x, y)
... 
>>> c=C(42)
>>> c.show(58)
*** (42,58) ***
>>> C.show(c,58)
*** (42,58) ***

26.1.5. Instance deletion: the destructor, .__del__()

When there are no values that refer to an instance any more, the storage occupied by the instance is recycled. However, if there are certain cleanup operations that must be done (such as closing external files), these operations can be placed into a destructor method that will be called before recycling the instance. Here is the general form of a destructor:

    def __del__(self):
        ...cleanup statements...