Online Book Reader

Home Category

Learning Python - Mark Lutz [437]

By Root 1615 0
Other to Spam’s class method. This works in this example because fetching the counter finds it in Spam by inheritance. If this method tried to assign to the passed class’s data, though, it would update Object, not Spam! In this specific case, Spam is probably better off hardcoding its own class name to update its data, rather than relying on the passed-in class argument.

Counting instances per class with class methods

In fact, because class methods always receive the lowest class in an instance’s tree:

Static methods and explicit class names may be a better solution for processing data local to a class.

Class methods may be better suited to processing data that may differ for each class in a hierarchy.

Code that needs to manage per-class instance counters, for example, might be best off leveraging class methods. In the following, the top-level superclass uses a class method to manage state information that varies for and is stored on each class in the tree—similar in spirit to the way instance methods manage state information in class instances:

class Spam:

numInstances = 0

def count(cls): # Per-class instance counters

cls.numInstances += 1 # cls is lowest class above instance

def __init__(self):

self.count() # Passes self.__class__ to count

count = classmethod(count)

class Sub(Spam):

numInstances = 0

def __init__(self): # Redefines __init__

Spam.__init__(self)

class Other(Spam): # Inherits __init__

numInstances = 0

>>> x = Spam()

>>> y1, y2 = Sub(), Sub()

>>> z1, z2, z3 = Other(), Other(), Other()

>>> x.numInstances, y1.numInstances, z1.numInstances

(1, 2, 3)

>>> Spam.numInstances, Sub.numInstances, Other.numInstances

(1, 2, 3)

Static and class methods have additional advanced roles, which we will finesse here; see other resources for more use cases. In recent Python versions, though, the static and class method designations have become even simpler with the advent of function decoration syntax—a way to apply one function to another that has roles well beyond the static method use case that was its motivation. This syntax also allows us to augment classes in Python 2.6 and 3.0—to initialize data like the numInstances counter in the last example, for instance. The next section explains how.

Decorators and Metaclasses: Part 1

Because the staticmethod call technique described in the prior section initially seemed obscure to some users, a feature was eventually added to make the operation simpler. Function decorators provide a way to specify special operation modes for functions, by wrapping them in an extra layer of logic implemented as another function.

Function decorators turn out to be general tools: they are useful for adding many types of logic to functions besides the static method use case. For instance, they may be used to augment functions with code that logs calls made to them, checks the types of passed arguments during debugging, and so on. In some ways, function decorators are similar to the delegation design pattern we explored in Chapter 30, but they are designed to augment a specific function or method call, not an entire object interface.

Python provides some built-in function decorators for operations such as marking static methods, but programmers can also code arbitrary decorators of their own. Although they are not strictly tied to classes, user-defined function decorators often are coded as classes to save the original functions, along with other data, as state information. There’s also a more recent related extension available in Python 2.6 and 3.0: class decorators are directly tied to the class model, and their roles overlap with metaclasses.

Function Decorator Basics

Syntactically, a function decorator is a sort of runtime declaration about the function that follows. A function decorator is coded on a line by itself just before the def statement that defines a function or method. It consists of the @ symbol, followed by what we call a metafunction—a function (or other callable object) that manages another function. Static methods

Return Main Page Previous Page Next Page

®Online Book Reader