Gibt es in Python einen Dekorator, der „@property' entspricht, um eine Klasseneigenschaft zu definieren?

Mary-Kate Olsen
Freigeben: 2024-11-11 00:52:03
Original
582 Leute haben es durchsucht

Is there a decorator equivalent to `@property` in Python for defining a class property?

So definieren Sie eine Klasseneigenschaft in Python

In Python kann der @classmethod-Dekorator verwendet werden, um einer Klasse eine Methode hinzuzufügen. Gibt es jedoch einen entsprechenden Dekorator zum Definieren einer Eigenschaft für eine Klasse?

Klasseneigenschaftsdekorator

Um diese Frage zu beantworten, betrachten wir das folgende Beispiel:

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

In diesem Beispiel besteht die Absicht darin, eine Klasseneigenschaft I mithilfe des @classproperty-Dekorators zu definieren. Es wird jedoch der Fehler „NameError: Name ‚classproperty‘ ist nicht definiert“ ausgelöst.

Lösung

Um eine Klasseneigenschaft zu erstellen, kann eine benutzerdefinierte Deskriptorklasse namens ClassPropertyDescriptor verwendet werden verwendet werden:

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

Die ClassPropertyDescriptor-Klasse definiert das Verhalten der Klasseneigenschaft. Es implementiert die Methoden __get__ und __set__, um das Abrufen und Festlegen des Eigenschaftswerts zu verwalten.

Klasseneigenschaftsdekorator

Um die Verwendung des Klasseneigenschaftsdeskriptors zu vereinfachen, wurde ein Dekorator namens @ Klasseneigenschaft kann erstellt werden:

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

    return ClassPropertyDescriptor(func)
Nach dem Login kopieren

Beispielverwendung

Wenn der benutzerdefinierte Klasseneigenschaftsdeskriptor und -dekorator vorhanden ist, kann das Beispiel wie folgt umgeschrieben werden:

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

Dieser Code definiert eine Klasseneigenschaftsleiste, auf die wie erwartet zugegriffen und sie geändert werden kann. Durch Ändern des Eigenschaftswerts für die Klasseninstanz oder für die Klasse selbst wird der Wert für alle Instanzen der Klasse aktualisiert.

Das obige ist der detaillierte Inhalt vonGibt es in Python einen Dekorator, der „@property' entspricht, um eine Klasseneigenschaft zu definieren?. 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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage