Können Klasseneigenschaften mit einem Decorator in Python definiert werden?

DDD
Freigeben: 2024-11-11 04:08:03
Original
934 Leute haben es durchsucht

Can Class Properties Be Defined With a Decorator in Python?

Klasseneigenschaften in Python

In Python können Klassenmethoden mithilfe des @classmethod-Dekorators hinzugefügt werden. Aber was ist mit Klasseneigenschaften? Gibt es einen Dekorator für sie?

Bedenken Sie diesen 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
Nach dem Login kopieren

Der Code definiert eine Klasse Beispiel mit einer Instanzeigenschaft i, einer Klasseneigenschaft I und zwei Klassenmethoden inc_i und inc_I .

Allerdings ist die für @classproperty verwendete Syntax in Python nicht korrekt. Um eine Klasseneigenschaft zu erstellen, können wir den folgenden Ansatz verwenden:

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)
Nach dem Login kopieren

Mit diesem Hilfscode können wir Klasseneigenschaften wie folgt definieren:

class Bar(object):

    _bar = 1

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

    @bar.setter
    def bar(cls, value):
        cls._bar = value
Nach dem Login kopieren

Der Klasseneigenschaften-Dekorator erstellt einen Deskriptor die die Get- und Set-Operationen für die Klasseneigenschaft abwickelt.

Durch Hinzufügen einer Metaklassendefinition können wir auch das Festlegen der Klasseneigenschaft direkt für die Klasse handhaben:

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
Nach dem Login kopieren

Jetzt beide Instanzen und Klasseneigenschaften können wie erwartet verwendet und festgelegt werden.

Das obige ist der detaillierte Inhalt vonKönnen Klasseneigenschaften mit einem Decorator in Python definiert werden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage