I l@ve RuBoard Previous Section Next Section

6.3 Using the Class Statement

Did all of the above make sense? If not, don't worry; now that we've had a quick tour, we're going to dig a bit deeper and study the concepts we've introduced in more detail. We met the class statement in our first examples, but let's formalize some of the ideas we introduced. As in C++, the class statement is Python's main OOP tool. Unlike in C++, class isn't really a declaration; like def, class is an object builder, and an implicit assignment梬hen run, it generates a class object, and stores a reference to it in the name used in the header.

6.3.1 General Form

As we saw on our quick tour, class is a compound statement with a body of indented statements under it. In the header, superclasses are listed in parentheses after the class name, separated by commas. Listing more than one superclass leads to multiple inheritance (which we'll say more about later in this chapter):

class <name>(superclass,...):       # assign to name
    data = value                    # shared class data
    def method(self,...):           # methods
        self.member = value         # per-instance data

Within the class statement, specially-named methods overload operators; for instance, a function called _ _ init __ is called at instance object construction time, if defined.

6.3.2 Example

At the start of this chapter, we mentioned that classes are mostly just namespaces?/i> a tool for defining names (called attributes) that export data and logic to clients. So how do you get from the statement to a namespace?

Here's how. Just as with modules, the statements nested in a class statement body create its attributes. When Python executes a class statement (not a call to a class), it runs all the statements in its body from top to bottom. Assignments that happen during this process create names in the class's local scope, which become attributes in the associated class object. Because of this, classes resemble both modules and functions:

The main distinction for classes is that their namespaces are also the basis of inheritance in Python; attributes are fetched from other classes if not found in a class or instance object. Because class is a compound statement, any sort of statement can be nested inside its body梖or instance, print, =, if, and def. As we've seen, nested defs make class methods, but other assignments make attributes too. For example, suppose we run the following class:

class Subclass(aSuperclass):               # define subclass
    data = 'spam'                          # assign class attr
    def __init__(self, value):             # assign class attr
        self.data = value                  # assign instance attr
    def display(self):
        print self.data, Subclass.data     # instance, class

This class contains two defs, which bind class attributes to method functions. It also contains a = assignment statement; since the name data is assigned inside the class, it lives in the class's local scope and becomes an attribute of the class object. Like all class attributes, data is inherited and shared by all instances of the class:[2]

[2] If you've used C++, you may recognize this as similar to the notion of C++'s static class data梞embers that are stored in the class, independent of instances. In Python, it's nothing special: all class attributes are just names assigned in the class statement, whether they happen to reference functions (C++'s methods) or something else (C++'s members).

>>> x = Subclass(1)             # make two instance objects
>>> y = Subclass(2)             # each has its own "data"
>>> x.display(); y.display()    # "self.data" differs, "Subclass.data" same
1 spam
2 spam

When we run this code, the name data lives in two places梚n instance objects (created in the __ init __ constructor) and in the class they inherit names from (created by the = assignment). The class's display method prints both versions, by first qualifying the self instance, and then the class itself. Since classes are objects with attributes, we can get to their names by qualifying, even if there's no instance involved.

I l@ve RuBoard Previous Section Next Section