python笔记 mixin

340 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情

0 环境

  • 编辑器:pycharm或者vscode
  • 系统版本:windows10
  • python版本:3.9.6

1 前言

直到看了官方的drf文档,有的python基础教程里,很少看到它的身影,很不巧我看的是python快速入门(看不到稀有生物mixin),导致当时看大佬的项目,稀里糊涂的,虽然用的不多,但是既然用了,我可以不会写,总得会看吧,然后有意思的是,vue中也有混入(mixin),不谈它们的作用是否不同,既然出现了,说明得学一下的。

image.png

2 mixin

想像一下这么个场景,我定义了一个Base类,由于某种原因,它是不可修改的,而它还有两个子类,A和B类,我现在想给Base类加个show方法,但是Base类不可修改,那么在定义ShowA和ShowB类分别继承A和B子类,如下图: image.png

我在加个装饰器的方式,如下方式: 我定义了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()

image.png

但是多用用会发现上面的方式,比较死板,比如复用等问题,然而用了mixin就不同了,我只需要定义一个类,然后把它放到ShowA参数中即可,达到的效果和之前的一样,那么mixin中,self.val怎么可以拿到值的呢,更像是组合,把这个类的方法和另一个类的属性拼在一起。是不是看到多继承的影子了。 image.png

我在show方法中,也可以直接调用到Base类的init的。 image.png

mixin也是可以有父的。 image.png

要想这个子mixin生效,需要父mixin在show方法中加个return返回值,和装饰器一样的效果。 image.png

3 总结

mixin有点像AOP,还有正常Mixin类放在继承列表的首位,mixin也是有限制的,不可以有初始化方法,虽然它也是class配def,但是它的定位有点像辅助,不能独自工作,需要和某个类一起使用,mixin类的父也要是mixin类。