Metaclass

Stack overflow

La metaclasse, è un componente che crea le classi, una ‘class factory’. Si utilizza come oggetto per semplificare la creazione dinamica di classi, come si può vedere in altri modi per definire una classe.

La metaclasse è usata per modificare la classe automaticamente al momento della crezione, come ad esempio per avere tutti gli attributi in maiuscolo.

Di base, type è una metaclasse, e infatti una qualsiasi metaclasse eredita da type.

# metaclasse
class M(type):
	def __call__(cls,*args,**kwargs):
		return super().__call__(*args, **kwargs)
 
class Foo(<lista classi base>, metaclass=M): pass

Il compilatore, se trova una metaclass nella definizione di una classe, userà quella al posto di type che solitamente è usato di default. Se la metaclasse non implementa il metodo __call__, verrà risalita la catena ereditaria, fino a type.

Creazione classi a runtime

Il metodo __call__ della classe type, con il giusto numero e tipo di parametri può anche fare altro.

class A: pass
 
# si possono anche definire funzioni, e poi associarle ad un attributo
def echo_bar(self):
	print(self.bar)
 
H = type('FooChild', (A,), {'x':0,'g':lambda self: self.x})

Classi create in questa maniera dinamica, possono coesistere con altre classi che hanno lo stesso nome (in questo caso “FooChild”), ma saranno fondamentalmente differenti. L’identificatore, o handle, della classe in questo caso è H.


Si possono anche passare keyword arguments alla metaclass:

class Foo(metaclass=something, kargv1=arg1, kargv2=arg2):

Una metaclasse può essere un qualsiasi callable, ovvero anche una funzione.

python_book6