django rest framework(下面简称 drf)
面向对象的三个特性:封装、多态、继承
<1> 子类重写父类方法
在继承父类的时候往往会重写父类中的方法,例如:
b = B() # 实例化
b.get_name() # 输出 B
b.return_name() # 输出 name:B,这里由于 B 类中没有实现 return_name 方法,实例化 B 得到 b 之后,会调用父类 A 中的 return_name 方法,hasattr 方法会查找类中是否有 name 属性,这里虽然在类 A 中没有,会向下找 B 类中是否有 name 属性,然后返回 'name:' + getattr(self, 'name', None),也就是 name: "b"。
在这个简单的子类方法重写父类方法,再使用 drf 的认证,权限等组件是会经常对父类中的方法重写,从而实现功能。
注意:如果像重写 python 内置的基本数据类型,如字典、列表中的特殊方法,就会得到意想不到的结果,就是实例化的对象不再调用自己重写的方法,而是调用本地的方法。这是因为 python 的一些基本数据类型的方法是由 C 语言编写的,python 为了满足速度,抄近道不会再调用自己重写的特殊方法。
<2> Mixin 模式
print(C.mro())
c= C()
c.f()
c.exral()
这样的继承虽然可以实现功能,但是有一个很明显的问题,那就是在面向对象中,一定要指明一个类到底是什么。如果想重构一个类,假如是 Nothing,那么让这个类实现会飞,会游泳,会跑,三种行为,可以同时继承,鸟、鱼、马三个类:
no = Nothing()
no.fly()
no.swim()
no.run()
可是实现会跑、会飞、会游泳的三种行为,但是这个类到底是什么,是鱼、是马、还是鸟,不知道 Nothing 到底是个什么类。为解决这个问题,可以引用 Mixin 模式:
这样就解决了上面的问题,也许你会发现,这其实没有什么变化,只是在类的命名加上了以 Mixin 结尾,其实这是一种默认的声明,可以知道 Nothing 类其实是一种马,父类是 Horse,继承其它两个类,只是为了调用它们的方法而已,这种叫做 Mixin 模式,在 drf 的源码中会用到。
# 例如 drf 中的 generics 路径为 rest_framework/generics.py
相当于每多一次继承,子类可调用的方法就更多了。