metaclass confict(元类冲突)的清晰含义初步定义了metaclass并了解简单使用之后,我们开始正式探究metaclass conflict,一个最简单触发metaclass conflict的例子如下:
In [42]: class M0(type):...:pass...:In [43]: class M1(type):...:pass...:In [44]: class A(metaclass=M0):...:pass...:In [45]: class B(metaclass=M1):...:pass...:In [46]: class C(A, B):...:pass...:---------------------------------------------------------------------------TypeErrorTraceback (most recent call last)<ipython-input-46-9900d594feda> in <module>----> 1 class C(A, B):2pass3TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
如上M0与M1为自定义metaclass,分别作为A、B的metaclass,当class C试图多继承A、B时就会出问题,从字面意思理解:子类的metaclass必须是其所有基类metaclass的(非严格)子类,看起来普通class的多继承和metaclass的多继承之间发生了什么问题 。这段话具体怎么理解?我们已经知道A、B都分别具有自己的metaclass M0、M1,那么当C多继承A、B的时候C的metaclass应该是M0还是M1呢?由于M0、M1两者之间并没有继承关系,用哪个都不行,Python不知道怎么办,只能告诉你出问题了 。
解决方案那理想情况下C的metaclass到底应该是什么呢?理想情况应该如下所示:
M0M1 : \/ : :\ /: AM2B\:/\ : /C
即采用多继承了M0、M1的M2作为C的metaclass,这也是解决这个问题的最终方案,具体代码如下:
In [58]: class M2(M0, M1):...:pass...:In [59]: class C(A, B, metaclass=M2):...:pass...:
如上我们通过手动定义M2,并手动明确指定class C的metaclass为M2,如此解决metaclass conflict问题 。这时再回到开头碰到的多继承abc.ABC与admin.ModelAdmin时遇到的问题就很容易理解了:因为abc.ABC有自己的metaclass abc.ABCMeta,同时modelAdmin也有自己的metaclass django.forms.widgets.MediaDefiningClass,并且这两者之间没有继承关系,因而 class MyAdmin(abc.ABC, admin.ModelAdmin) 多继承时解释器无法推断出满足条件的metaclass,自然也就报错了,解决办法和上面的方案一样,定义一个两者metaclass的子类并将其指定为MyAdmin的metaclass即可,代码如下:
In [112]: print(type(abc.ABC), type(admin.ModelAdmin))<class 'abc.ABCMeta'> <class 'django.forms.widgets.MediaDefiningClass'>In [113]: class MyMeta(type(abc.ABC), type(admin.ModelAdmin)):...:pass...:In [114]: class MyAdmin(abc.ABC, admin.ModelAdmin, metaclass=MyMeta):...:pass...:In [115]: print(type(MyAdmin))<class '__main__.MyMeta'>
转载请注明出处,原文地址:python_metaclass_conflict_study.html" rel="external nofollow noreferrer">https://www.cnblogs.com/AcAc-t/p/python_metaclass_conflict_study.html
参考https://www.liaoxuefeng.com/wiki/1016959663602400/1017592449371072python" rel="external nofollow noreferrer">https://stackoverflow.com/questions/100003/what-are-metaclasses-in-pythonhttps://www.cnblogs.com/JetpropelledSnake/p/9094103.htmlpython/metatype.html" rel="external nofollow noreferrer">http://www.phyast.pitt.edu/~micheles/python/metatype.html
【Python 多重继承时metaclass conflict问题解决与原理探究】
经验总结扩展阅读
- 牛客 python试题解析1 - 入门级
- Python数据分析:实用向
- python ROS2时间同步
- 图文 Python 嵌入式打包
- 3 Python全栈工程师之从网页搭建入门到Flask全栈项目实战 - 入门Flask微框架
- 跟我学Python图像处理丨图像特效处理:毛玻璃、浮雕和油漆特效
- 四 Selenium4.0+Python3系列 - 常见元素操作(含鼠标键盘事件)
- 二、python基本数据类型
- 联想小新pro16重量_联想小新pro16有多重
- python3使用mutagen进行音频元数据处理