Python Language Metaclasses di base


Esempio

Quando il type viene chiamato con tre argomenti, si comporta come la (meta) classe che è, e crea una nuova istanza, es. produce una nuova classe / tipo.

Dummy = type('OtherDummy', (), dict(x=1))
Dummy.__class__              # <type 'type'> 
Dummy().__class__.__class__  # <type 'type'> 

È possibile sottoclasse il type per creare un metaclass personalizzato.

class mytype(type):
    def __init__(cls, name, bases, dict):
        # call the base initializer
        type.__init__(cls, name, bases, dict)

        # perform custom initialization...
        cls.__custom_attribute__ = 2

Ora abbiamo un nuovo metaclasse mytype personalizzato che può essere utilizzato per creare classi nello stesso modo del type .

MyDummy = mytype('MyDummy', (), dict(x=2))
MyDummy.__class__              # <class '__main__.mytype'>
MyDummy().__class__.__class__  # <class '__main__.mytype'>
MyDummy.__custom_attribute__   # 2

Quando creiamo una nuova classe usando la parola chiave della class il metaclasse viene scelto di default in base alle baseclass.

>>> class Foo(object):
...     pass

>>> type(Foo)
type

Nell'esempio precedente l'unica classe di base è l' object quindi il nostro metaclasse sarà il tipo di object , che è il type . È possibile sovrascrivere il valore predefinito, tuttavia dipende se utilizziamo Python 2 o Python 3:

Python 2.x 2.7

È possibile utilizzare un attributo speciale di livello di classe __metaclass__ per specificare il metaclass.

class MyDummy(object):
    __metaclass__ = mytype
type(MyDummy)  # <class '__main__.mytype'>
Python 3.x 3.0

Un argomento specifico per la parola chiave metaclass specifica il metaclass.

class MyDummy(metaclass=mytype):
    pass
type(MyDummy)  # <class '__main__.mytype'>

Tutti gli argomenti delle parole chiave (tranne il metaclass ) nella dichiarazione della classe verranno passati al metaclasse. Quindi la class MyDummy(metaclass=mytype, x=2) passerà x=2 come argomento della parola chiave al costruttore mytype .

Leggi questa descrizione approfondita delle meta-classi Python per maggiori dettagli.