Metaclass

A programozásban a metaklass egy osztály, amelynek példányai osztályok. Más szavakkal, a metaclass az osztály osztálya.

Tábornok

Az objektumorientált programozásban az osztály egyfajta modul, amely lehetővé teszi az objektumok részhalmazának létrehozását. Az osztály leírja, hogy az objektumai hogyan viselkednek, biztosítja az interfészüket, és összeállítja az állapotuk szerkezetét. Az osztály lehetővé teszi új objektumok létrehozását a példányosítás nevű mechanizmus segítségével. Ez a mechanizmus két műveletre bontható:

Reflektív programozási környezetekben az osztályok teljes értékű objektumoknak tekinthetők, amelyek a példányosítási mechanizmus ( hozzárendelés (); init () ) használatával jöttek létre . Ebben az esetben az összes osztály olyan példánynak tekinthető, amelyet a bázis létrehozott ugyanabból az osztályból.

Osztályt, amelynek példányai osztályok, metaciklusnak nevezzük (vegye figyelembe, hogy a meghatározás rekurzív). Mivel a metaclass osztály, ez is meghatározza példányainak viselkedését és állapotszerkezetét. Új metaklass létrehozásával tehát beavatkozunk az osztályok létrehozásának módjára, és ezért beavatkozunk magának a nyelvnek egy részére. Mechanizmuson keresztül, mint ez, a fejlesztő új funkciók a nyelv, mint a képesség, hogy nyomon metódushívások, a képesség, hogy hozzon létre singletons , sorosítás tárgyak XML formátumban, stb

Metaclasses nyelveken

A következő nyelvek lehetővé teszik a metaklassok meghatározását:

A java.lang.Class osztály egy metaosztály a Java nyelven .

Egyszerű példa

# interception de tous les attributs pour retourner une valeur par défaut # peut servir pour faire des bouchons par exemple ou restreindre la création # ou l'accès à des attributs… class MyMetaClasse(type): """une Metaclasse avec intercepteur : dès qu'on fait Maclasse.UnAttribut, name = UnAttribut, on renvoie une valeur par défaut """ def __getattr__(MaClasse, name): return 128 #Déclarer une classe, c'est instancier une métaclasse. class MaClasse: __metaclass__ = MyMetaClasse #Lien avec la metaclasse #Ensuite la définition de la classe continue print MaClasse.x, MaClasse.y #resultats 128 128

Egy másik példa

A Pythonban az alap metaklass típus neve . Az új metaklass létrehozása specializálódott típus szerint történik . Az allokációs () és az init () műveleteket a __új __ () és __init __ () metódusok képviselik . A __new __ () egy olyan osztálymódszer, amely négy paramétert vesz fel: magát a metaclass-ot, a példázott osztály nevét, annak szuperosztályait, valamint az összes metódusát és attribútumát tartalmazó szótárt. __init __ () egy példány metódus. Ennek paraméterei ugyanazok, mint amelyeket a __new __ () , kivéve az első, amely képviseli a példányosított esetében __init __ () .

Az alábbi példa egy metaklase Python-ban történő használatára mutat példát. Ez egy metaclass, amely lehetővé teszi a metódus hívásának nyomon követését.

from types import FunctionType class Tracer(type): def __new__(metacls, name, bases, dct): # définition d'une fonction wrapper pour les méthodes def _wrapper(method): # création d'une fonction permettant tracer une méthode def _trace(self, *args, **kwargs): print "(call %s with *%s **%s)" % (method.__name__, str(args), kwargs) return method(self, *args, **kwargs) # idiome: faire passer une fonction pour une autre _trace.__name__ = method.__name__ _trace.__doc__ = method.__doc__ _trace.__dict__.update(method.__dict__) return _trace # remplacement de toutes les méthodes par leur équivalent tracé newDct = {} for name, slot in dct.iteritems(): if type(slot) is FunctionType: newDct[name] = _wrapper(slot) else: newDct[name] = slot # appel au constructeur de la super classe (type) return type.__new__(metacls, name, bases, newDct)

A Tracer metaclass alapelve az , hogy átalakítja a példányok összes módszerét úgy, hogy azok üzenetet jelenítsenek meg, mielőtt folytatnák a végrehajtásukat. A metaclass konstruktor _wrapper () függvénye egy dekoratőr, vagyis bemeneti függvényt vesz fel, és módosított viselkedéssel adja vissza ezt a funkciót. Tudnia kell, hogy a konstruktor dct paraméterében a metódusoknak még mindig működési állapotban kell lenniük.

Itt van egy példa, amely bemutatja a metaclass használatát.

class A(object): # création de la liaison entre la classe et la métaclasse __metaclass__ = Tracer def __init__(self): self.a = 1 def get(self): return self.a >>> a = A() (call __init__ with *() **{}) >>> a.get() (call get with *() **{}) 1

Itt van egy példa a Delphiben.

// Voici comment est défini le type TComponentClass dans la VCL de delphi : type TComponentClass = class of TComponent;

A JavaScript-ben elég, ha egy osztályt adunk vissza a konstruktortól.

class ModelClass { constructor(name) { return class ModelInstance { constructor() { this.name = name; } }; } } const MyModel = new ModelClass('myModel') const instance = new MyModel(); // instance.name === 'myModel'

Lásd is