Online Book Reader

Home Category

Learning Python - Mark Lutz [409]

By Root 1335 0
instance by using the fully expanded name (e.g., I._C1__X = 77). On the other hand, this feature makes it less likely that you will accidentally step on a class’s names.

Pseudoprivate attributes are also useful in larger frameworks or tools, both to avoid introducing new method names that might accidentally hide definitions elsewhere in the class tree and to reduce the chance of internal methods being replaced by names defined lower in the tree. If a method is intended for use only within a class that may be mixed into other classes, the double underscore prefix ensures that the method won’t interfere with other names in the tree, especially in multiple-inheritance scenarios:

class Super:

def method(self): ... # A real application method

class Tool:

def __method(self): ... # Becomes _Tool__method

def other(self): self.__method() # Use my internal method

class Sub1(Tool, Super): ...

def actions(self): self.method() # Runs Super.method as expected

class Sub2(Tool):

def __init__(self): self.method = 99 # Doesn't break Tool.__method

We met multiple inheritance briefly in Chapter 25 and will explore it in more detail later in this chapter. Recall that superclasses are searched according to their left-to-right order in class header lines. Here, this means Sub1 prefers Tool attributes to those in Super. Although in this example we could force Python to pick the application class’s methods first by switching the order of the superclasses listed in the Sub1 class header, pseudoprivate attributes resolve the issue altogether. Pseudoprivate names also prevent subclasses from accidentally redefining the internal method’s names, as in Sub2.

Again, I should note that this feature tends to be of use primarily for larger, multiprogrammer projects, and then only for selected names. Don’t be tempted to clutter your code unnecessarily; only use this feature for names that truly need to be controlled by a single class. For simpler programs, it’s probably overkill.

For more examples that make use of the __X naming feature, see the lister.py mix-in classes introduced later in this chapter, in the section on multiple inheritance, as well as the discussion of Private class decorators in Chapter 38. If you care about privacy in general, you might want to review the emulation of private instance attributes sketched in the section Attribute Reference: __getattr__ and __setattr__ in Chapter 29, and watch for the Private class decorator in Chapter 38 that we will base upon this special method. Although it’s possible to emulate true access controls in Python classes, this is rarely done in practice, even for large systems.

* * *

[69] This tends to scare people with a C++ background unnecessarily. In Python, it’s even possible to change or completely delete a class method at runtime. On the other hand, almost nobody ever does this in practical programs. As a scripting language, Python is more about enabling than restricting. Also, recall from our discussion of operator overloading in Chapter 29 that __getattr__ and __setattr__ can be used to emulate privacy, but are generally not used for this purpose in practice. More on this when we code a more realistic privacy decorator Chapter 38.

Methods Are Objects: Bound or Unbound

Methods in general, and bound methods in particular, simplify the implementation of many design goals in Python. We met bound methods briefly while studying __call__ in Chapter 29. The full story, which we’ll flesh out here, turns out to be more general and flexible than you might expect.

In Chapter 19, we learned how functions can be processed as normal objects. Methods are a kind of object too, and can be used generically in much the same way as other objects—they can be assigned, passed to functions, stored in data structures, and so on. Because class methods can be accessed from an instance or a class, though, they actually come in two flavors in Python:

Unbound class method objects: no self

Accessing a function attribute of a class by qualifying the class returns an unbound method object.

Return Main Page Previous Page Next Page

®Online Book Reader