ProgramingTip

메타 클래스 다중 상속 불일치

bestdevel 2020. 12. 25. 10:28
반응형

메타 클래스 다중 상속 불일치


왜 이런거야 :

class MyType(type):
    def __init__(cls, name, bases, attrs):
        print 'created', cls
class MyMixin:
    __metaclass__ = MyType
class MyList(list, MyMixin): pass

좋아, 예상대로 작동합니다.

created <class '__main__.MyMixin'>
created <class '__main__.MyList'>

하지만 이것은 :

class MyType(type):
    def __init__(cls, name, bases, attrs):
        print 'created', cls
class MyMixin:
    __metaclass__ = MyType
class MyObject(object, MyMixin): pass

괜찮지 않아서 그렇게 폭발합니까? :

created <class '__main__.MyMixin'>
Traceback (most recent call last):
  File "/tmp/junk.py", line 11, in <module>
    class MyObject(object, MyMixin): pass
TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution
order (MRO) for bases object, MyMixin

사용자 지정 메타 클래스 문제가 아닙니다 ( 메타 클래스-step 에서 진단 되지만 ).

>>> class Normal(object): pass
... 
>>> class MyObject(object, Normal): pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution
order (MRO) for bases object, Normal

문제는 다음과 가변적입니다.

>>> class Derived(Normal): pass
... 
>>> class Ok(Derived, Normal): pass
... 
>>> class Nope(Normal, Derived): pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution
order (MRO) for bases Normal, Derived

즉, 기본 클래스에서 파생 클래스가 뒤 따르는 상속을 곱할 수 없습니다. 일반적인 MRO 제약 / 보장을 MRO를 정의하는 것은 불가능합니다.

많이도 그렇게 하고 싶지 는 않습니다 . 서브 클래스는 아마도 기본 클래스의 일부 메소드를 재정의하고 (일반적인 하위 클래스 가 수행하는 작업입니다 ;-) 기본 클래스를 "앞에"두는 "무시한 재정의"를 의미합니다.

파생 된 클래스 뒤에 기본 클래스를 배치하는 것은 거의 쓸모가 없지만 적어도 무해합니다 (일반 MRO 보장과 일치).

물론 작품의 첫 번째 예는 때문 MyMixin입니다 하지 에서 파생 list:

>>> MyMixin.__mro__
(<class '__main__.MyMixin'>, <type 'object'>)

...하지만이 되어 에서 파생 된 object(모든 현대적인 스타일의 파이썬 클래스처럼) 두 번째 예제 (매우 독립적으로 할 수없는 일 때문에 MyMixin사용자 정의 메타 클래스를 가짐).


여기에서 부모 클래스를 상속하고 있고 부모 클래스가 이미 다른 클래스를 상속하고 있으므로 부모 클래스가 이미 상속 한 클래스를 상속 할 필요가 없습니다.

예를 들면 :

class A(object):
.
.
class B(object, A):
.
.

A는 Object 클래스를 상속하고 B는 A를 상속하므로 오류가 발생하므로 간접적으로 B는 객체를 상속하므로 객체를 상속 할 필요가 없습니다. . . .

해결책은 클래스 B ... 인수 목록에서 객체 클래스를 제거하는 것입니다.

참조 URL : https://stackoverflow.com/questions/3003053/metaclass-multiple-inheritance-inconsistency

반응형