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
このコードは、インスタンス プロパティ i、クラス プロパティ I、および 2 つのクラス メソッド inc_i と inc_I を持つクラス Example を定義します。 .
ただし、@classproperty に使用される構文は Python では正しくありません。クラス プロパティを作成するには、次のアプローチを使用できます。
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)
このヘルパー コードを使用すると、次のようにクラス プロパティを定義できます。
class Bar(object): _bar = 1 @classproperty def bar(cls): return cls._bar @bar.setter def bar(cls, value): cls._bar = value
クラス プロパティ デコレーターは記述子を作成します。
メタクラス定義を追加することで、クラス プロパティの設定をクラス プロパティに直接処理することもできます。 class:
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
これで、インスタンスとクラスのプロパティの両方を期待どおりに使用および設定できるようになりました。
以上がPython のデコレータを使用してクラス プロパティを定義できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。