Online Book Reader

Home Category

Learning Python - Mark Lutz [418]

By Root 1514 0
returns constructed string;

uses __X attr names to avoid impacting clients;

uses generator expr to recurse to superclasses;

uses str.format() to make substitutions clearer

__module__=lister

__str__=

........>

For more fun, try mixing this class into something more substantial, like the Button class of Python’s tkinter GUI toolkit module. In general, you’ll want to name ListTree first (leftmost) in a class header, so its __str__ is picked up; Button has one, too, and the leftmost superclass is searched first in multiple inheritance. The output of the following is fairly massive (18K characters), so run this code on your own to see the full listing (and if you’re using Python 2.6, recall that you should use Tkinter for the module name instead of tkinter):

>>> from lister import ListTree

>>> from tkinter import Button # Both classes have a __str__

>>> class MyButton(ListTree, Button): pass # ListTree first: use its __str__

...

>>> B = MyButton(text='spam')

>>> open('savetree.txt', 'w').write(str(B)) # Save to a file for later viewing

18247

>>> print(B) # Print the display here

_ListTree__visited={}

_name=44355632

_tclCommands=[]

...much more omitted...

>

Of course, there’s much more we could do here (sketching the tree in a GUI might be a natural next step), but we’ll leave further work as a suggested exercise. We’ll also extend this code in the exercises at the end of this part of the book, to list superclass names in parentheses at the start of instance and class displays.

The main point here is that OOP is all about code reuse, and mix-in classes are a powerful example. Like almost everything else in programming, multiple inheritance can be a useful device when applied well. In practice, though, it is an advanced feature and can become complicated if used carelessly or excessively. We’ll revisit this topic as a gotcha at the end of the next chapter. In that chapter, we’ll also meet the new-style class model, which modifies the search order for one special multiple inheritance case.

* * *

Note


Supporting slots: Because they scan instance dictionaries, the ListInstance and ListTree classes presented here don’t directly support attributes stored in slots—a newer and relatively rarely used option we’ll meet in the next chapter, where instance attributes are declared in a __slots__ class attribute. For example, if in textmixin.py we assign __slots__=['data1'] in Super and __slots__=['data3'] in Sub, only the data2 attribute is displayed in the instance by these two lister classes; ListTree also displays data1 and data3, but as attributes of the Super and Sub class objects and with a special format for their values (technically, they are class-level descriptors).

To better support slot attributes in these classes, change the __dict__ scanning loops to also iterate through __slots__ lists using code the next chapter will present, and use the getattr built-in function to fetch values instead of __dict__ indexing (ListTree already does). Since instances inherit only the lowest class’s __slots__, you may also need to come up with a policy when __slots__ lists appear in multiple superclasses (ListTree already displays them as class attributes). ListInherited is immune to all this, because dir results combine both __dict__ names and all classes’ __slots__ names.

Alternatively, as a policy we could simply let our code handle slot-based attributes as it currently does, rather than complicating it for a rare, advanced feature. Slots and normal instance attributes are different kinds of names. We’ll investigate slots further in the next chapter; I omitted addressing them in these examples to avoid a forward dependency (not counting this note, of course!)—not exactly a valid design goal, but reasonable for a book.

* * *

Classes Are Objects: Generic Object Factories

Sometimes, class-based designs require objects to be created in response to conditions that can’t be predicted when a program is written. The factory

Return Main Page Previous Page Next Page

®Online Book Reader