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 ?

Pourquoi ne puis-je pas utiliser `property()` avec Classmethods en Python et quelles sont les solutions de contournement ?

DDD
Libérer: 2024-12-12 21:28:12
original
265 Les gens l'ont consulté

Why Can't I Use `property()` with Classmethods in Python, and What Are the Workarounds?

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)
Copier après la connexion

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
Copier après la connexion

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)
Copier après la connexion

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
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal