Online Book Reader

Home Category

Learning Python - Mark Lutz [442]

By Root 1712 0
name Spam is assigned in the generate function’s local scope. However, in versions of Python prior to 2.2, within the class’s method function the class name Spam is not visible—method has access only to its own local scope, the module surrounding generate, and built-in names:

def generate(): # Fails prior to Python 2.2, works later

class Spam:

count = 1

def method(self): # Name Spam not visible:

print(Spam.count) # not local (def), global (module), built-in

return Spam()

generate().method()

C:\python\examples> python nester.py

...error text omitted...

Print(Spam.count) # Not local (def), global (module), built-in

NameError: Spam

This example works in Python 2.2 and later because the local scopes of all enclosing function defs are automatically visible to nested defs (including nested method defs, as in this example). However, it doesn’t work before 2.2 (we’ll look at some possible solutions momentarily).

Note that even in 2.2 and later, method defs cannot see the local scope of the enclosing class; they can only see the local scopes of enclosing defs. That’s why methods must go through the self instance or the class name to reference methods and other attributes defined in the enclosing class statement. For example, code in the method must use self.count or Spam.count, not just count.

If you’re using a release prior to 2.2, there are a variety of ways to get the preceding example to work. One of the simplest is to move the name Spam out to the enclosing module’s scope with a global declaration. Because method sees global names in the enclosing module, references to Spam will work:

def generate():

global Spam # Force Spam to module scope

class Spam:

count = 1

def method(self):

print(Spam.count) # Works: in global (enclosing module)

return Spam()

generate().method() # Prints 1

A better alternative would be to restructure the code such that the class Spam is defined at the top level of the module by virtue of its nesting level, rather than using global declarations. The nested method function and the top-level generate will then find Spam in their global scopes:

def generate():

return Spam()

class Spam: # Define at top level of module

count = 1

def method(self):

print(Spam.count) # Works: in global (enclosing module)

generate().method()

In fact, this approach is recommended for all Python releases—code tends to be simpler in general if you avoid nesting classes and functions.

If you want to get complicated and tricky, you can also get rid of the Spam reference in method altogether by using the special __class__ attribute, which returns an instance’s class object:

def generate():

class Spam:

count = 1

def method(self):

print(self.__class__.count) # Works: qualify to get class

return Spam()

generate().method()

Delegation-Based Classes in 3.0: __getattr__ and built-ins

We met this issue briefly in our class tutorial in Chapter 27 and our delegation coverage in Chapter 30: classes that use the __getattr__ operator overloading method to delegate attribute fetches to wrapped objects will fail in Python 3.0 unless operator overloading methods are redefined in the wrapper class. In Python 3.0 (and 2.6, when new-style classes are used), the names of operator overloading methods implicitly fetched by built-in operations are not routed through generic attribute-interception methods. The __str__ method used by printing, for example, never invokes __getattr__. Instead, Python 3.0 looks up such names in classes and skips the normal runtime instance lookup mechanism entirely. To work around this, such methods must be redefined in wrapper classes, either by hand, with tools, or by definition in superclasses. We’ll revisit this gotcha in Chapters 37 and 38.

“Overwrapping-itis”

When used well, the code reuse features of OOP make it excel at cutting development time. Sometimes, though, OOP’s abstraction potential can be abused to the point of making code difficult to understand. If classes are layered too deeply, code can become obscure; you may have to search through

Return Main Page Previous Page Next Page

®Online Book Reader