Online Book Reader

Home Category

Learning Python - Mark Lutz [528]

By Root 1455 0
other words, beyond their technical model, decorators offer some advantages in terms of code maintenance and aesthetics. Moreover, as structuring tools, decorators naturally foster encapsulation of code, which reduces redundancy and makes future changes easier.

Decorators do have some potential drawbacks, too—when they insert wrapper logic, they can alter the types of the decorated objects, and they may incur extra calls. On the other hand, the same considerations apply to any technique that adds wrapping logic to objects.

We’ll explore these tradeoffs in the context of real code later in this chapter. Although the choice to use decorators is still somewhat subjective, their advantages are compelling enough that they are quickly becoming best practice in the Python world. To help you decide for yourself, let’s turn to the details.

The Basics

Let’s get started with a first-pass look at decoration behavior from a symbolic perspective. We’ll write real code soon, but since most of the magic of decorators boils down to an automatic rebinding operation, it’s important to understand this mapping first.

Function Decorators

Function decorators have been available in Python since version 2.5. As we saw earlier in this book, they are largely just syntactic sugar that runs one function through another at the end of a def statement, and rebinds the original function name to the result.

Usage

A function decorator is a kind of runtime declaration about the function whose definition follows. The decorator is coded on a line just before the def statement that defines a function or method, and it consists of the @ symbol followed by a reference to a metafunction—a function (or other callable object) that manages another function.

In terms of code, function decorators automatically map the following syntax:

@decorator # Decorate function

def F(arg):

...

F(99) # Call function

into this equivalent form, where decorator is a one-argument callable object that returns a callable object with the same number of arguments as F:

def F(arg):

...

F = decorator(F) # Rebind function name to decorator result

F(99) # Essentially calls decorator(F)(99)

This automatic name rebinding works on any def statement, whether it’s for a simple function or a method within a class. When the function F is later called, it’s actually calling the object returned by the decorator, which may be either another object that implements required wrapping logic, or the original function itself.

In other words, decoration essentially maps the first of the following into the second (though the decorator is really run only once, at decoration time):

func(6, 7)

decorator(func)(6, 7)

This automatic name rebinding accounts for the static method and property decoration syntax we met earlier in the book:

class C:

@staticmethod

def meth(...): ... # meth = staticmethod(meth)

class C:

@property

def name(self): ... # name = property(name)

In both cases, the method name is rebound to the result of a built-in function decorator, at the end of the def statement. Calling the original name later invokes whatever object the decorator returns.

Implementation

A decorator itself is a callable that returns a callable. That is, it returns the object to be called later when the decorated function is invoked through its original name—either a wrapper object to intercept later calls, or the original function augmented in some way. In fact, decorators can be any type of callable and return any type of callable: any combination of functions and classes may be used, though some are better suited to certain contexts.

For example, to tap into the decoration protocol in order to manage a function just after it is created, we might code a decorator of this form:

def decorator(F):

# Process function F

return F

@decorator

def func(): ... # func = decorator(func)

Because the original decorated function is assigned back to its name, this simply adds a post-creation step to function definition. Such a structure might be used

Return Main Page Previous Page Next Page

®Online Book Reader