第四部分第11章,接口:从协议到抽象基类(重点讲抽象基类)
1. Python喜欢序列
class Foo:
def __getitem__(self, pos):
return range(0, 30, 10)[pos]
f = Foo()
# 1. f[]调用__getitem__
print(f[1])
# 2. 没有__iter__方法,转而调用__getitem__方法,传入从0开始的整数索引,尝试迭代对象(这是一种后备机制)
for i in f:
print(i)
# 3. 没有__contains__方法,转而调用__getitem__方法
print(20 in f)
2. 使用猴子补丁在运行时实现协议
def set_card(deck, position, card):
deck._cards[position] = card
#猴子补丁,把自定义的函数赋值给__setitem__,把它变成可变的。
FrenchDeck.__setitem__ = set_card
3. 直接使用抽象基类,而不只将其当作文档。
class Struggle:
def __len__(self):
return 23
from collections import abc
#True
print(isinstance(Struggle(), abc.Sized))
isinstance(the_arg, collections.abc.Sequence)
#1. 假设是单个字符串风格(EAFP风格)
try:
#2. 把逗号替换成空格,然后拆分成名称列表。
field_names =
field_names.replace(',', ' ').split()
#3. 如果field_names看起来不像是字符串
except AttributeError:
#4. 假设已经是由名称组成的可迭代对象
pass
#5. 为了确保的确是可迭代对象,也为了保存一份副本,使用所得值创建一个元组。
field_names = tuple(field_names)
4. !继承抽象基类
5. !标准库中的抽象基类
5.1 collections.abc模块中的抽象基类
5.2 numbers的抽象基类
6. 定义并使用一个抽象基类
7. Python使用register
8. 鹅(本章提到了goose typing)的行为有可能像鸭子
class Struggle:
def __len__(self):
return 23
from collections import abc
isinstance(Struggle(), abc.Sized)
issubclass(Struggle, abc.Sized)