Propriétés de classe en Python
En Python, des méthodes de classe peuvent être ajoutées à l'aide du décorateur @classmethod. Mais qu’en est-il des propriétés de classe ? Y a-t-il un décorateur pour eux ?
Considérez ce code :
class Example(object): the_I = 10 def __init__(self): self.an_i = 20 @property def i(self): return self.an_i def inc_i(self): self.an_i += 1 # is this even possible? @classproperty def I(cls): return cls.the_I @classmethod def inc_I(cls): cls.the_I += 1
Le code définit un exemple de classe avec une propriété d'instance i, une propriété de classe I et deux méthodes de classe inc_i et inc_I .
Cependant, la syntaxe utilisée pour @classproperty n'est pas correcte en Python. Pour créer une propriété de classe, nous pouvons utiliser l'approche suivante :
class ClassPropertyDescriptor(object): def __init__(self, fget, fset=None): self.fget = fget self.fset = fset def __get__(self, obj, klass=None): if klass is None: klass = type(obj) return self.fget.__get__(obj, klass)() def __set__(self, obj, value): if not self.fset: raise AttributeError("can't set attribute") type_ = type(obj) return self.fset.__get__(obj, type_)(value) def setter(self, func): if not isinstance(func, (classmethod, staticmethod)): func = classmethod(func) self.fset = func return self def classproperty(func): if not isinstance(func, (classmethod, staticmethod)): func = classmethod(func) return ClassPropertyDescriptor(func)
Avec ce code d'assistance, nous pouvons définir les propriétés de classe comme suit :
class Bar(object): _bar = 1 @classproperty def bar(cls): return cls._bar @bar.setter def bar(cls, value): cls._bar = value
Le décorateur classproperty crée un descripteur qui gère les opérations get et set pour la propriété de classe.
En ajoutant une définition de métaclasse, nous pouvons également gérer la définition de la propriété de classe directement sur la classe :
class ClassPropertyMetaClass(type): def __setattr__(self, key, value): if key in self.__dict__: obj = self.__dict__.get(key) if obj and type(obj) is ClassPropertyDescriptor: return obj.__set__(self, value) return super(ClassPropertyMetaClass, self).__setattr__(key, value) Bar.__metaclass__ = ClassPropertyMetaClass
Maintenant, les deux instances et les propriétés de classe peuvent être utilisées et définies comme prévu.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!