如何在 Python 中定義類別屬性
在 Python 中,@classmethod 裝飾器可用於新增方法至類別。但是,是否有一個等效的裝飾器來定義類別的屬性?
類別屬性裝飾器
為了回答這個問題,讓我們考慮以下範例:
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
在此範例中,目的是使用@classproperty 裝飾器定義一個類別屬性。但是,會出現錯誤「NameError:name 'classproperty'未定義」。
解決方案
要建立類別屬性,可以使用名為ClassPropertyDescriptor 的自訂描述符類別使用:
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
類別屬性裝飾器
為了更容易使用類別屬性描述符,一個名為 @的裝飾器可以建立類別屬性:def classproperty(func): if not isinstance(func, (classmethod, staticmethod)): func = classmethod(func) return ClassPropertyDescriptor(func)
範例用法
使用自訂類別屬性描述符和裝飾器後,範例可以重寫為:class Bar(object): _bar = 1 @classproperty def bar(cls): return cls._bar @bar.setter def bar(cls, value): cls._bar = value
以上是Python 中是否有相當於「@property」的裝飾器來定義類別屬性?的詳細內容。更多資訊請關注PHP中文網其他相關文章!