《流畅的python》读书笔记(六)
11.2 python喜欢序列
接口是指实现了一套完整的协议的类, 只定义了方法, 而没有实现具体功能, 必须被继承后实现.
比如序列接口,包括Container协议支持in运算(contains), Iterable协议支持迭代运算(iter),Sized支持len运算( len) , 可变序列还包括__setitem__
如果没有实现iter和contains, 会调用getitem支持迭代和in运算.
python数据模型的涉及哲学是尽量支持基本协议
11.3 猴子补丁
<1>定义功能函数
<2>新增类属性=功能函数名
11.4 水禽/鸭子类型
不关注对象属于哪个类, 而关注对象是实现了那些接协议.
尽量不要使用type(obj)== class 进行判断, isinstance(sub, class)可以用来判断抽象基类的对象.
继承抽象基类只需要实现所需的方法
抽象基类用于封装和抽象框架引入的一般性概念, 不适合出现在生产代码中.
11.6 标准库中的抽象基类
标准库中的抽象大多数在collections.abc模块中.
11.12 延伸阅读
抽象基类方法装饰器@abstractmethod
interface包提供了声明接口的方式
在编译时监察类型的而语言是静态语言, 在运行时检查类型的语言是动态语言.
强类型语言: 很少隐式转换类型, C++, Java, Python
弱类型语言: PHP, JavaScript, Perl
python是动态强类型语言
适配器设计模式可以解决打了猴子补丁的两个库可能互相牵绊的问题.
python不允许为内置类型打猴子补丁.
12.1 子类化内置类型
内置类型是用C语言编写, 直接子类化内置类型不会调用被用户重写后的方法.
应通过继承collections中的UserDict, UserList, UserString进行子类化.
io模块中的抽象基类名称以Base结尾.
12.4 多重继承
接口继承是框架的支柱
单纯为多个子类提供方法,而本身没有抽象含义的类应声明为混入, 名称以Mixin结尾.
.
通过类的继承,组合和委托来实现代码的复用.
应优先使用实例的组合而不是继承.
自定义的子类, 只能有一个具体类作为超类, 其余的均应是抽象类或混入
<<面向对象分析与设计(第3版)>> Grady Booch
13.1 运算符重载基础
is, not, and, or不能重载.
13.2 一元运算符
取正 + pos, 通常情况下 +x == x,
但是在精度不同的上下文中 +x != x
13.3 重载运算符
重载__add__运算符时, 如果因为类型不兼容导致异常,应该将其捕获,然后返回NotImplemented, 这样解释器会自动调用反向方法, 如果仍不兼容, python会抛出TypeError异常.
decimal.Decimal不是numbers.Real的虚拟子类.
矩阵乘法(点乘)运算符 @ matmul
对于 == 如果发生 NotImplemented, python会自动调用反向方法, 如果再次抛出 NotImplemented, python会比较ID, 如果不相等返回False, != 的结果与==相反.