2013-01-07 1 views
10

파이썬 상속, 메타 클래스 및 유형() 함수 :다음 코드는 아래에 설명 된 특정 방식, 행동 이유를 이해할 수없는

from abc import ABCMeta 

class PackageClass(object): 
    __metaclass__ = ABCMeta   

class MyClass1(PackageClass): 
    pass 

MyClass2 = type('MyClass2', (PackageClass,), {}) 

print MyClass1 
print MyClass2 

>>> <class '__main__.MyClass1'> 
>>> <class 'abc.MyClass2'> 

이유는 무엇입니까 repr(MyClass2)이 (abc.MyClass2을 말한다 방법이 아니다 것입니다 참된)? 감사합니다.

+2

프로젝트 구조는 여기서는 전혀 상관없는 것처럼 보입니다. 내가 그 부분을 제거하고 그냥 1 모듈로 (모든 설명 된 행동은 아직 거기에있다)하는 것이 좋습니다 것입니다. – mgilson

+0

@mgilson주의 해 주셔서 감사합니다. –

+1

그리고 부수적으로이 동작은 여전히 ​​python3.x에서 유지됩니다 (그냥 테스트했습니다) – mgilson

답변

6

이 문제는 ABCMeta__new__을 무시하고 그 슈퍼 클래스 생성자 (type())를 호출하기 때문에 발생합니다. type()은 해당 호출 컨텍스트 에서 새 클래스의 __module__을 파생합니다. 이 경우 type 호출은 abc 모듈에서 발생한 것처럼 보입니다. 따라서 새로운 클래스는 을 abc으로 설정합니다 (type()은 실제 클래스 구성이 __main__에서 발생했음을 알 수 없으므로).

쉬운 방법은 주변 단지 유형을 생성 한 후 __module__ 직접 설정하는 것입니다 :

MyClass2 = type('MyClass2', (PackageClass,), {}) 
MyClass2.__module__ = __name__ 

는 또한 버그 리포트를 제출에게 추천 할 것입니다.

관련

: Base metaclass overriding __new__ generates classes with a wrong __module__, Weird inheritance with metaclasses

1 : typenew method 그것이 메타 클래스의 생성자를 호출하지 않는 한 __module__로 현재 글로벌 __name__, 를 사용 C. 그것의에 정의 된 유형의 객체입니다.

+0

이렇게 자세한 답변을 해주셔서 감사합니다. –

관련 문제