Python 多重繼承時metaclass conflict問題解決與原理探究( 二 )


解決方案那理想情況下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

推薦閱讀