Um Ihre Augen zu fangen:Kann Metaklasse aufrufbar sein?
Ich denke, die Dokumentation könnte falsch sein!
Gemäß Python 2.7.12 Dokumentation, 3.4.3. Customizing Klasse creation¶:
__metaclass__
Diese Variable kann jede aufrufbare akzeptieren Argumente für Namen, Basen und dict sein. Bei der Klassenerstellung wird anstelle des eingebauten das aufrufbaretype()
verwendet.Neu in Version 2.2. Jedoch
, this article argumentiert:
Q: Wow! Kann ich ein beliebiges Objekt als
__metaclass__
verwenden?A: Nein. Es muss eine Unterklasse vom Typ des Basisobjekts sein. ...
Also habe ich ein Experiment auf meinem eigenen:
class metacls(list): # <--- subclassing list, rather than type
def __new__(mcs, name, bases, dict):
dict['foo'] = 'metacls was here'
return type.__new__(mcs, name, bases, dict)
class cls(object):
__metaclass__ = metacls
pass
Das gibt mir:
Traceback (most recent call last):
File "test.py", line 6, in <module>
class cls(object):
File "test.py", line 4, in __new__
return type.__new__(mcs, name, bases, dict)
TypeError: Error when calling the metaclass bases
type.__new__(metacls): metacls is not a subtype of type
So ist das Dokument wirklich falsch?
"gebunden an" bedeutet "eine Unterklasse von", oder? –
@sunqingyao: Nein, "gebunden" bedeutet zugeordnet. Die Zuweisung 'Foo = []' wird ausgeführt. Eine 'class'-Anweisung wird grundsätzlich als Funktion behandelt; Der Body wird wie in einer Funktion ausgeführt und alle lokalen Namen werden in ein Dictionary extrahiert. Dann wird das Klassenobjekt erzeugt, indem man 'bodydict.get ('__ metaclass__', type)' (also entweder den Wert von '__metaclass__' oder, falls fehlt,' type') aufruft und den Klassennamen, die Klassenbasen und das Körperwörterbuch. * Was zurückgegeben wird * wird dem Namen der Klasse zugewiesen. Binding ist der Fachausdruck; andere Dinge binden auch, wie 'import' oder' for'. –
Aber mit der Aussage "' mcs 'ist an' liste' gebunden ", scheinst du zu meinen,' 'mcs' ist eine Instanz einer Unterklasse von' list' ". –