Online Book Reader

Home Category

Learning Python - Mark Lutz [366]

By Root 1758 0
it is a dictionary, we can fetch its keys list, index by key, iterate over its keys, and so on, to process all attributes generically. We can use this here to print every attribute in any instance, not just those we hardcode in custom displays.

Here’s what these tools look like in action at Python’s interactive prompt. Notice how we load Person at the interactive prompt with a from statement here—class names live in and are imported from modules, exactly like function names and other variables:

>>> from person import Person

>>> bob = Person('Bob Smith')

>>> print(bob) # Show bob's __str__

[Person: Bob Smith, 0]

>>> bob.__class__ # Show bob's class and its name

>>> bob.__class__.__name__

'Person'

>>> list(bob.__dict__.keys()) # Attributes are really dict keys

['pay', 'job', 'name'] # Use list to force list in 3.0

>>> for key in bob.__dict__:

print(key, '=>', bob.__dict__[key]) # Index manually

pay => 0

job => None

name => Bob Smith

>>> for key in bob.__dict__:

print(key, '=>', getattr(bob, key)) # obj.attr, but attr is a var

pay => 0

job => None

name => Bob Smith

As noted briefly in the prior chapter, some attributes accessible from an instance might not be stored in the __dict__ dictionary if the instance’s class defines __slots__, an optional and relatively obscure feature of new-style classes (and all classes in Python 3.0) that stores attributes in an array and that we’ll discuss in Chapters 30 and 31. Since slots really belong to classes instead of instances, and since they are very rarely used in any event, we can safely ignore them here and focus on the normal __dict__.

A Generic Display Tool

We can put these interfaces to work in a superclass that displays accurate class names and formats all attributes of an instance of any class. Open a new file in your text editor to code the following—it’s a new, independent module named classtools.py that implements just such a class. Because its __str__ print overload uses generic introspection tools, it will work on any instance, regardless of its attributes set. And because this is a class, it automatically becomes a general formatting tool: thanks to inheritance, it can be mixed into any class that wishes to use its display format. As an added bonus, if we ever want to change how instances are displayed we need only change this class, as every class that inherits its __str__ will automatically pick up the new format when it’s next run:

# File classtools.py (new)

"Assorted class utilities and tools"

class AttrDisplay:

"""

Provides an inheritable print overload method that displays

instances with their class names and a name=value pair for

each attribute stored on the instance itself (but not attrs

inherited from its classes). Can be mixed into any class,

and will work on any instance.

"""

def gatherAttrs(self):

attrs = []

for key in sorted(self.__dict__):

attrs.append('%s=%s' % (key, getattr(self, key)))

return ', '.join(attrs)

def __str__(self):

return '[%s: %s]' % (self.__class__.__name__, self.gatherAttrs())

if __name__ == '__main__':

class TopTest(AttrDisplay):

count = 0

def __init__(self):

self.attr1 = TopTest.count

self.attr2 = TopTest.count+1

TopTest.count += 2

class SubTest(TopTest):

pass

X, Y = TopTest(), SubTest()

print(X) # Show all instance attrs

print(Y) # Show lowest class name

Notice the docstrings here—as a general-purpose tool, we want to add some functional documentation for potential users to read. As we saw in Chapter 15, docstrings can be placed at the top of simple functions and modules, and also at the start of classes and their methods; the help function and the PyDoc tool extracts and displays these automatically (we’ll look at docstrings again in Chapter 28).

When run directly, this module’s self-test makes two instances and prints them; the __str__ defined here shows the instance’s class, and all its attributes names and values, in sorted attribute name order:

C:\misc> classtools.py

[TopTest: attr1=0, attr2=1]

[SubTest: attr1=2,

Return Main Page Previous Page Next Page

®Online Book Reader