クラスのプロパティを定義するための Python の `@property` に相当するデコレータはありますか?

Mary-Kate Olsen
リリース: 2024-11-11 00:52:03
オリジナル
573 人が閲覧しました

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

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 デコレーターを使用してクラス プロパティ I を定義することが目的です。ただし、「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
ログイン後にコピー

ClassPropertyDescriptor クラスは、次の動作を定義します。クラスのプロパティ。プロパティ値の取得と設定を処理する __get__ メソッドと __set__ メソッドを実装します。

クラス プロパティ デコレーター

クラス プロパティ記述子の使用を容易にするために、@ というデコレーターが使用されています。クラスプロパティは次のように作成できます:

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 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート