Maison  >  Article  >  développement back-end  >  Comment créer des propriétés de classe en Python sans décorateur dédié ?

Comment créer des propriétés de classe en Python sans décorateur dédié ?

Patricia Arquette
Patricia Arquetteoriginal
2024-11-07 15:22:03414parcourir

How to create class properties in Python without a dedicated decorator?

Comment créer une propriété de classe

Une propriété de classe est un moyen pratique d'accéder aux attributs via la classe elle-même plutôt que via des instances de la classe. En Python, des méthodes peuvent être ajoutées à une classe à l'aide du décorateur @classmethod, mais il n'existe pas de décorateur de ce type pour les propriétés. Cependant, un effet similaire peut être obtenu grâce à une classe de descripteur personnalisée.

Classe de descripteur personnalisée

Le code suivant définit une classe de descripteur personnalisée, ClassPropertyDescriptor, qui permet la création de propriétés de classe :

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

Class Property Decorator

Pour simplifier la création de propriétés de classe, une fonction de décorateur classproperty est définie :

def classproperty(func):
    if not isinstance(func, (classmethod, staticmethod)):
        func = classmethod(func)

    return ClassPropertyDescriptor(func)

Exemple d'utilisation

Le code suivant montre comment utiliser le décorateur classproperty pour définir une propriété de classe nommée bar dans la classe Bar :

class Bar(object):

    _bar = 1

    @classproperty
    def bar(cls):
        return cls._bar

    @bar.setter
    def bar(cls, value):
        cls._bar = value

Métaclasse

Pour permettre la définition directe des propriétés de classe via la classe, une définition de métaclasse, ClassPropertyMetaClass, est utilisée :

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)

En ajoutant __metaclass__ à la définition de classe Bar et en mettant à jour le Méthode __set__ de ClassPropertyDescriptor, la possibilité de définir les propriétés de classe via la classe elle-même est activée.

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!

Déclaration:
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