2013-01-07 11 views
10

ich nicht verstehen kann, warum der folgende Code eine bestimmte Art und Weise verhält, die im Folgenden beschrieben wird: Warum tutPython Vererbung, metaclasses und Typ() Funktion

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) sagt abc.MyClass2 (die übrigens nicht wahr)? Vielen Dank!

+2

Die Projektstruktur scheint hier völlig irrelevant zu sein. Ich würde empfehlen, diesen Teil zu entfernen und alles als 1 Modul zu haben (das beschriebene Verhalten ist immer noch da). – mgilson

+0

@mgilson Danke für die Kenntnisnahme, aktualisiert. –

+1

Und, als eine Randnotiz, hält dieses Verhalten noch in python3.x (ich habe es gerade getestet) – mgilson

Antwort

6

Das Problem rührt von der Tatsache her, dass ABCMeta__new__ überschreibt und seinen Superklassenkonstruktor (type()) dort aufruft. type() leitet die __module__ für die neue Klasse aus ihrem Aufrufkontext ab ; In diesem Fall scheint der type Anruf von dem abc Modul zu kommen. Daher hat die neue Klasse __module__abc festgelegt (seit type() hat keine Möglichkeit zu wissen, dass der eigentliche Klassenaufbau in __main__ stattfand).

Der einfache Weg ist um zu __module__ sich nur einstellen, nach der Art zu schaffen:

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

Ich würde auch empfehlen, einen Fehlerbericht einzureichen.

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

1: type ist eine Art Objekt in C. Sein definiert new method die aktuelle globale __name__ als __module__ verwendet, es sei denn, es einen metaclass Konstruktor aufruft.

+0

Vielen Dank für eine so detaillierte Antwort, @nneonneo! –