持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情
0 环境
- 编辑器:pycharm或者vscode
- 系统版本:windows10
- python版本:3.9.6
1 前言
直到看了官方的drf文档,有的python基础教程里,很少看到它的身影,很不巧我看的是python快速入门(看不到稀有生物mixin),导致当时看大佬的项目,稀里糊涂的,虽然用的不多,但是既然用了,我可以不会写,总得会看吧,然后有意思的是,vue中也有混入(mixin),不谈它们的作用是否不同,既然出现了,说明得学一下的。
2 mixin
想像一下这么个场景,我定义了一个Base类,由于某种原因,它是不可修改的,而它还有两个子类,A和B类,我现在想给Base类加个show方法,但是Base类不可修改,那么在定义ShowA和ShowB类分别继承A和B子类,如下图:
我在加个装饰器的方式,如下方式:
我定义了Base类,并初始化了,打印val的值,定义两个子类A,B,什么都不加,又定义了装饰器,它的目的,动态的给类加方法,不要还想着动态增加成员,此路不通。ShowA继承了A,并加了个@show_to_base,这样就可以使用show方法了。最终结果,先打印Base初始化里的内容,然后再打印调用show方法里的内容。
class Base:
def __init__(self, val):
self.val = val
print(f"base --> {val}")
class A(Base):
pass
class B(Base):
pass
def show_to_base(cls):
def _show(self):
print("show -->", self.val)
cls.show = _show
return cls
@show_to_base
class ShowA(A):
def __init__(self, val):
super(A, self).__init__(val)
s = ShowA("123")
s.show()
但是多用用会发现上面的方式,比较死板,比如复用等问题,然而用了mixin就不同了,我只需要定义一个类,然后把它放到ShowA参数中即可,达到的效果和之前的一样,那么mixin中,self.val怎么可以拿到值的呢,更像是组合,把这个类的方法和另一个类的属性拼在一起。是不是看到多继承的影子了。
我在show方法中,也可以直接调用到Base类的init的。
mixin也是可以有父的。
要想这个子mixin生效,需要父mixin在show方法中加个return返回值,和装饰器一样的效果。
3 总结
mixin有点像AOP,还有正常Mixin类放在继承列表的首位,mixin也是有限制的,不可以有初始化方法,虽然它也是class配def,但是它的定位有点像辅助,不能独自工作,需要和某个类一起使用,mixin类的父也要是mixin类。