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
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)
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
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
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!