同步阅读进度,多语言翻译,过滤屏幕蓝光,评论分享,更多完整功能,更好读书体验,试试 阅读 ‧ 电子书库
Abstract Superclasses
Notice how the Provider class in the prior example works. When we call the delegate method through a Provider instance, two independent inheritance searches occur:
This “filling in the blanks” sort of coding structure is typical of OOP frameworks. At least in terms of the delegate method, the superclass in this example is what is sometimes called an abstract superclass—a class that expects parts of its behavior to be provided by its subclasses. If an expected method is not defined in a subclass, Python raises an undefined name exception when the inheritance search fails.
Class coders sometimes make such subclass requirements more obvious with assert statements, or by raising the built-in NotImplementedError exception with raise statements (we’ll study statements that may trigger exceptions in depth in the next part of this book). As a quick preview, here’s the assert scheme in action:
class Super:
def delegate(self):
self.action()
def action(self):
assert False, 'action must be defined!' # If this version is called
>>> X = Super()
>>> X.delegate()
AssertionError: action must be defined!
We’ll meet assert in Chapters 32 and 33; in short, if its first expression evaluates to false, it raises an exception with the provided error message. Here, the expression is always false so as to trigger an error message if a method is not redefined, and inheritance locates the version here. Alternatively, some classes simply raise a NotImplementedError exception directly in such method stubs to signal the mistake:
class Super:
def delegate(self):
self.action()
def action(self):
raise NotImplementedError('action must be defined!')
>>> X = Super()
>>> X.delegate()
NotImplementedError: action must be defined!
For instances of subclasses, we still get the exception unless the subclass provides the expected method to replace the default in the superclass:
>>> class Sub(Super): pass
...
>>> X = Sub()
>>> X.delegate()
NotImplementedError: action must be defined!
>>> class Sub(Super):
... def action(self): print('spam')
...
>>> X = Sub()
>>> X.delegate()
spam
For a somewhat more realistic example of this section’s concepts in action, see the “Zoo animal hierarchy” exercise (exercise 8) at the end of Chapter 31, and its solution in Part VI, Classes and OOP in Appendix B. Such taxonomies are a traditional way to introduce OOP, but they’re a bit removed from most developers’ job descriptions.
请支持我们,让我们可以支付服务器费用。
使用微信支付打赏