Maison >développement back-end >Tutoriel Python >Pourquoi ne puis-je pas utiliser `property()` avec Classmethods en Python et quelles sont les solutions de contournement ?
Utilisation de property() avec classmethod : une exploration
En Python, la fonction property() joue un rôle crucial dans la création de getters et de setters pour les attributs de classe. Cependant, tenter d'utiliser property() avec des méthodes de classe, qui sont décorées avec le décorateur @classmethod, peut entraîner des erreurs inattendues.
Considérons l'extrait de code suivant qui illustre le problème :
class Foo(object): _var = 5 @classmethod def getvar(cls): return cls._var @classmethod def setvar(cls, value): cls._var = value var = property(getvar, setvar)
Lorsque nous essayons d'accéder ou de définir l'attribut var sur une instance de la classe Foo, nous rencontrons un erreur :
>>> f = Foo() >>> f.getvar() 5 >>> f.setvar(4) >>> f.getvar() 4 >>> f.var Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'classmethod' object is not callable
Comme expliqué dans la documentation et dans les discussions sur le débordement de pile [Méthode de classe Python en tant que Setter et Getter](https://stackoverflow.com/questions/27906399/python-class-method-as -setter-and-getter), il n'est pas possible d'utiliser la fonction property() avec les méthodes de classe en Python 3.8 et plus tôt.
Cependant, il existe des approches alternatives pour obtenir la fonctionnalité souhaitée :
Pour Python 2 et Python 3 (y compris 3.9-3.10) :
Puisqu'une propriété affecte une instance, mais qu'une propriété de classe est créée sur la classe, il est nécessaire de créer la propriété sur la métaclasse.
class Foo(object): _var = 5 class __metaclass__(type): # Python 2 syntax for metaclasses pass @classmethod def getvar(cls): return cls._var @classmethod def setvar(cls, value): cls._var = value Foo.__metaclass__.var = property(Foo.getvar.im_func, Foo.setvar.im_func)
Pour les versions Python à partir de 3.9 :
Une solution plus propre consiste à déplacer les méthodes de classe vers la métaclasse et à déclarer la propriété directement sur la métaclasse :
class Foo_meta(type): @property def var(cls): return cls._var @var.setter def var(cls, value): cls._var = value class Foo(metaclass=Foo_meta): _var = 5
Ces méthodes alternatives permettent effectivement d'utiliser des propriétés au niveau 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!