Metaclasse

In programmazione a oggetti, una metaclasse è una classe le cui istanze sono a loro volta classi. Questo concetto è strettamente legato al concetto di riflessione (reflection), che si applica a quegli strumenti concettuali che permettono di rappresentare, all'interno di un programma, informazioni sulle parti costituenti del programma stesso (tipicamente classi e oggetti).

Il concetto di metaclasse è impiegato soprattutto a livello teorico (appare, per esempio, nella definizione formale della semantica dello Unified Modeling Language), ma trova anche applicazioni dirette in diversi linguaggi di programmazione. In Java, per esempio, tutte le classi sono concettualmente considerate istanze dell'unica metaclasse Class, in Python type è una metaclasse.

In Python una metaclasse è per lo più definita come una sottoclasse di type.

 class AttributeInitType(type):
     def __call__(self, *args, **kwargs):
         """ Create a new instance. """
 
         # First, create the object in the normal default way.
         obj = type.__call__(self, *args)
 
         # Additionally, set attributes on the new object.
         for name, value in kwargs.items():
             setattr(obj, name, value)
 
         # Return the new object.
         return obj

Questa metaclasse sovrascrive solamente la creazione dell'oggetto. Tutti gli altri aspetti della classe e comportamento dell'oggetto sono ancora gestiti da type. Ora la classe Car può essere riscritta per usare questa metaclasse. In Python 2 si fa assegnando __metaclass__ nella definizione di classe mentre in Python 3 fornendo all'argomento della classe metaclass = M)

 class Car(object):
     __metaclass__ = AttributeInitType
     __slots__ = ['make', 'model', 'year', 'color']
 
     @property
     def description(self):
         """ Return a description of this car. """
         return "%s %s %s %s" % (self.color, self.year, self.make, self.model)

Gli oggetti Car si possono istanziare così:

 cars = [
     Car(make='Toyota', model='Prius', year=2005, color='green'),
     Car(make='Ford', model='Prefect', year=1979, color='blue')]

Un altro esempio di Metaclasse in Python:

class Spell(type):
    def __new__(cls,classname,super,classdict):
        def pph( hours ): return lambda self : self.pay_per_hour * hours

        classdict['pay_per_hour'] = 12
        classdict['day_salary'] = pph(8)
        classdict['week_salary'] = pph(8*5)
        classdict['year_salary'] = pph(8*5*4*12)
        classdict['month_salary'] = pph(8*5*4)
        return type.__new__(cls, classname, super, classdict )

class Person(metaclass=Spell):
    def __init__(self,name,lastname,bday):
        self.name = name
        self.lastname = lastname
        self.bday = bday

    def get_name(self):
        return self._name
    def get_lastname(self):
        return self._lastname
    def get_bday(self):
        return self._bday
    def __repr__(self):
        return "name: {0}, lastname: {1}, bday: {2}".format(self.name,self.lastname,self.bday)
      
if __name__ == "__main__":
    persona = Person("Mario","Rossi","23 novembre 65")

Linguaggi che supportano le metaclassi

[modifica | modifica wikitesto]

Voci correlate

[modifica | modifica wikitesto]