14 votes

Comment initialiser les classes (et non les instances) en Python ?

Je souhaite fusionner les contraintes de la classe actuelle et des classes héritées uniquement lorsqu'une classe est chargée (et non par objet !).

class Domain(Validatable):

    constraints = {...}

Pour ce faire, j'ai défini une méthode _initialize_class_not_instance qui doit être appelée une fois pour chaque classe :

class Validatable:

    @classmethod
    def _initialize_class_not_instance(cls):
        # merge constraints from derived class and base classes
        pass

    __class__._initialize_class_not_instance() # doesn't work
    # Validatable._merge_constraints() # doesn't work too

Le problème est que __class__ n'existe pas dans ce contexte et Validatable n'est pas non plus défini. Mais je veux éviter que l'utilisateur de mon API doive appeler explicitement la méthode d'initialisation ou utiliser un décorateur de classe supplémentaire.

Une idée sur la manière d'initialiser la classe ?

17voto

Utiliser une métaclasse.

class MetaClass(type):
  def __init__(cls, name, bases, d):
    type.__init__(cls, name, bases, d)
    cls.foo = 42

class MyClass(object):
  __metaclass__ = MetaClass

print MyClass.foo

2voto

deamon Points 15181

Je me suis retrouvé avec un décorateur de classe et sans héritage. Ce décorateur fusionne les contraintes de la classe actuelle et de la classe héritée et surcharge la fonction __init__ méthode :

def validatable(cls):

    # merge constraints from derived class and base classes here ...

    original_init = cls.__init__
    def init_to_insert(self, *args, **keywords):
        self.errors = {}
        original_init(self, *args, **keywords)   
    cls.__init__ = init_to_insert
    return cls

C'est la clé de ma solution, puisque le décorateur doit modifier la classe (en fusionnant les contraintes et en insérant des méthodes) et les instances.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X