Maison > Article > développement back-end > Existe-t-il un décorateur équivalent à « @property » en Python pour définir une propriété de classe ?
Comment définir une propriété de classe en Python
En Python, le décorateur @classmethod peut être utilisé pour ajouter une méthode à une classe. Cependant, existe-t-il un décorateur équivalent pour définir une propriété pour une classe ?
Décorateur de propriété de classe
Pour répondre à cette question, considérons l'exemple suivant :
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 e = Example() assert e.i == 20 e.inc_i() assert e.i == 21 assert Example.I == 10 Example.inc_I() assert Example.I == 11
Dans cet exemple, l'intention est de définir une propriété de classe I à l'aide du décorateur @classproperty. Cependant, l'erreur "NameError : le nom 'classproperty' n'est pas défini" est générée.
Solution
Pour créer une propriété de classe, une classe de descripteur personnalisée appelée ClassPropertyDescriptor peut être utilisé :
import inspect 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") if inspect.isclass(obj): type_ = obj obj = None else: 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
La classe ClassPropertyDescriptor définit le comportement de la propriété de classe. Il implémente les méthodes __get__ et __set__ pour gérer l'obtention et la définition de la valeur de la propriété.
Décorateur de propriété de classe
Pour faciliter l'utilisation du descripteur de propriété de classe, un décorateur appelé @ classproperty peut être créé :
def classproperty(func): if not isinstance(func, (classmethod, staticmethod)): func = classmethod(func) return ClassPropertyDescriptor(func)
Exemple d'utilisation
Avec le descripteur et le décorateur de propriété de classe personnalisés en place, l'exemple peut être réécrit comme :
class Bar(object): _bar = 1 @classproperty def bar(cls): return cls._bar @bar.setter def bar(cls, value): cls._bar = value
Ce code définit une barre de propriétés de classe accessible et modifiable comme prévu. La modification de la valeur de la propriété sur l'instance de classe ou sur la classe elle-même mettra à jour la valeur de toutes les instances de la classe.
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!