__Metaclass__ non dovrebbe forzare l'uso di una metaclasse in Python?
-
03-07-2019 - |
Domanda
Ho cercato di conoscere le metaclasse in Python. Ho avuto l'idea principale, ma non riesco ad attivare il meccanismo. A quanto ho capito, puoi specificare M come metaclasse durante la costruzione di una classe K impostando __metaclass__
su M a livello globale o di classe. Per provarlo, ho scritto il seguente programma:
p = print
class M(type):
def __init__(*args):
type.__init__(*args)
print("The rain in Spain")
p(1)
class ClassMeta:
__metaclass__ = M
p(2)
__metaclass__ = M
class GlobalMeta: pass
p(3)
M('NotMeta2', (), {})
p(4)
Tuttavia, quando lo eseguo, ottengo il seguente output:
C:\Documents and Settings\Daniel Wong\Desktop>python --version Python 3.0.1 C:\Documents and Settings\Daniel Wong\Desktop>python meta.py 1 2 3 The rain in Spain 4
Non dovrei vedere " La pioggia in Spagna " dopo 1 e 2? Cosa sta succedendo qui?
Soluzione
In Python 3 (che stai utilizzando) le metaclasse sono specificate da un parametro parola chiave nella definizione della classe:
class ClassMeta(metaclass=M):
pass
Specificare una proprietà di classe __metaclass__
o una variabile globale è una vecchia sintassi di Python 2.x e non è più supportata. Vedi anche " Novità di Python 3 " e < a href = "http://www.python.org/dev/peps/pep-3115/" rel = "nofollow noreferrer"> PEP 2115 .
Altri suggerimenti
Funziona come previsto in Python 2.6 (e precedenti), ma in 3.0 le metaclasse sono specificate diversamente:
class ArgMeta(metaclass=M): ...
La sintassi delle metaclass è modificata in Python 3.0. L'attributo __metaclass__
non è più speciale né a livello di classe né a livello di modulo. Per fare ciò che stai cercando di fare, devi specificare metaclass
come argomento di parola chiave nell'istruzione class
:
p = print
class M(type):
def __init__(*args):
type.__init__(*args)
print("The rain in Spain")
p(1)
class ClassMeta(metaclass=M): pass
I rendimenti:
1
The rain in Spain
Come ti aspetteresti.