2017-10-01 3 views
0

Warum in dem Code unten Metaklasse mit Objektbasis auslösen Metaklasse Konflikt Ausnahme?Warum erhöht Metaklasse mit Objektbasis den Metaklassenkonflikt?

"metaclass Konflikt: die Metaklasse einer abgeleiteten Klasse muss eine (nicht streng) Unterklasse der metaclasses aller Basen"

class M_A(object): pass 
class A(object, metaclass = M_A): pass 

Das Gleiche gilt für einen anderen Code:

class M_A(list): pass 
class A(object, metaclass = M_A): pass 

ich verstehe, dass die CPython den obigen Code wie interpretieren:

A = M_A.__new__(M_A, 'A', (object,), {}) 

Was mich verwirrt ist, dass die Basisklasse von A ist Objekt, und jede Klasse ist Unterklasse von Objekt. Dieser Fehler ist so seltsam. Was ist los mit mir?

+1

'M_A' nicht eine Unterklasse eines metaclass jeder Basisklasse von' A' ist. 'class M_A (type): pass' wird wahrscheinlich funktionieren. – vaultah

+0

Was mich verwirrt ist, dass die Basisklasse von A ist * Objekt *, und jede Klasse ist Unterklasse von * Objekt *. Ist M_A (list) eine Unterklasse einer Metaklasse irgendeiner Basisklasse von A? Ich denke, es ist. – ahui

+0

@ahui 'M_A (Liste)' ist eine Unterklasse von 'Objekt', ja. Aber darum geht es in der Fehlermeldung nicht. 'M_A' muss eine Unterklasse von' object' _metaclass_ sein, was 'type' ist. –

Antwort

3

Schauen wir uns diese Fehlermeldung einen genaueren Blick:

metaclass Konflikt: die Metaklasse einer abgeleiteten Klasse muss eine (nicht streng) Unterklasse der metaclasses aller Basen

Dies ist ein wenig verwirrend, so lassen Sie uns einen Blick darauf werfen, was was ist:

  • Die „abgeleitete Klasse“ist.
  • Die "Metaklasse einer abgeleiteten Klasse"A ist M_A.
  • A 's Basisklasse ist object daher "die metaclasses aller Basen" ist type - weil type ist object' s metaclass.

Das ist das Problem - object 's metaclass type, aber A' s Metaklasse ist M_A. Da M_A keine Unterklasse von type ist, weiß python nicht, welche Metaklasse für A verwendet werden soll und gibt einen Fehler aus.


Um dies zu beheben, die Klasse der M_A zu type Eltern ändern:

class M_A(type): pass 
class A(object, metaclass = M_A): pass 

# no errors thrown 
Verwandte Themen