示例 11-14 把 Tombola.register 当作类装饰器使用。在 Python 3.3 之前的版本中不能这样使用 register,必须在定义类之后像普通函数那样调用,如示例 11-14 中最后那行注释所述。

虽然现在可以把 register 当作装饰器使用了,但更常见的做法还是把它当作函数使用,用于注册其他地方定义的类。例如,在 collections.abc 模块的源码中(https://hg.python.org/cpython/file/3.4/Lib/_collections_abc.py),是这样把内置类型 tuplestrrangememoryview 注册为 Sequence 的虚拟子类的:

Sequence.register(tuple)
Sequence.register(str)
Sequence.register(range)
Sequence.register(memoryview)

其他几个内置类型在 _collections_abc.py 文件(https://hg.python.org/cpython/file/3.4/Lib/_collections_abc.py)中注册为抽象基类的虚拟子类。这些类型在导入模块时注册,这样做是可以的,因为必须导入才能使用抽象基类:能访问 MutableMapping 才能编写 isinstance(my_dict, MutableMapping)

结束本章之前,还要解释一下 Alex Martelli 在“水禽和抽象基类”中施展的魔法。