预计阅读本页时间:-
Python 2.6 and 3.0 Abstract Superclasses
As of Python 2.6 and 3.0, the prior section’s abstract superclasses (a.k.a. “abstract base classes”), which require methods to be filled in by subclasses, may also be implemented with special class syntax. The way we code this varies slightly depending on the version. In Python 3.0, we use a keyword argument in a class header, along with special @ decorator syntax, both of which we’ll study in detail later in this book:
from abc import ABCMeta, abstractmethod
class Super(metaclass=ABCMeta):
@abstractmethod
def method(self, ...):
pass
广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元
But in Python 2.6, we use a class attribute instead:
class Super:
__metaclass__ = ABCMeta
@abstractmethod
def method(self, ...):
pass
Either way, the effect is the same—we can’t make an instance unless the method is defined lower in the class tree. In 3.0, for example, here is the special syntax equivalent of the prior section’s example:
>>> from abc import ABCMeta, abstractmethod
>>>
>>> class Super(metaclass=ABCMeta):
... def delegate(self):
... self.action()
... @abstractmethod
... def action(self):
... pass
...
>>> X = Super()
TypeError: Can't instantiate abstract class Super with abstract methods action
>>> class Sub(Super): pass
...
>>> X = Sub()
TypeError: Can't instantiate abstract class Sub with abstract methods action
>>> class Sub(Super):
... def action(self): print('spam')
...
>>> X = Sub()
>>> X.delegate()
spam
Coded this way, a class with an abstract method cannot be instantiated (that is, we cannot create an instance by calling it) unless all of its abstract methods have been defined in subclasses. Although this requires more code, the advantage of this approach is that errors for missing methods are issued when we attempt to make an instance of the class, not later when we try to call a missing method. This feature may also be used to define an expected interface, automatically verified in client classes.
Unfortunately, this scheme also relies on two advanced language tools we have not met yet—function decorators, introduced in Chapter 31 and covered in depth in Chapter 38, as well as metaclass declarations, mentioned in Chapter 31 and covered in Chapter 39—so we will finesse other facets of this option here. See Python’s standard manuals for more on this, as well as precoded abstract superclasses Python provides.
[66] This description isn’t 100% complete, because we can also create instance and class attributes by assigning to objects outside class statements—but that’s a much less common and sometimes more error-prone approach (changes aren’t isolated to class statements). In Python, all attributes are always accessible by default. We’ll talk more about attribute name privacy in Chapter 29 when we study __setattr__, in Chapter 30 when we meet __X names, and again in Chapter 38, where we’ll implement it with a class decorator.