1

クラスの一部としていくつかのデータ記述子が欲しいのですが。つまり、クラス属性を実際にはプロパティにし、そのアクセスはクラスメソッドによって処理されるようにします。

Pythonはこれを直接サポートしていないようですが、typeクラスをサブクラス化することで実装できます。したがって、のサブクラスにプロパティを追加するtypeと、そのインスタンスにそのプロパティの記述子が含まれるようになります。そのインスタンスはクラスです。したがって、クラス記述子。

これはお勧めですか?注意すべき落とし穴はありますか?

4

2 に答える 2

1

これは、「クラス属性が実際にはプロパティであり、そのアクセスがクラスメソッドによって処理される」という意味ですか?

デコレータpropertyを使用して、アクセサを実際のデータメンバーのように見せることができます。次に、x.setterデコレータを使用して、その属性のセッターを作成できます。

から継承するようにしてください。継承しobjectないと、機能しません。

class Foo(object):
    def __init__(self):
            self._hiddenx = 3
    @property
    def x(self):
            return self._hiddenx + 10
    @x.setter
    def x(self, value):
            self._hiddenx = value

p = Foo()

p.x #13

p.x = 4
p.x #14
于 2010-07-18T20:15:40.887 に答える
1

記述子がクラスでアクセスされる場合、記述子オブジェクト自体を返すのは(通常)慣例です。これが何をするかpropertyです。クラスのプロパティオブジェクトにアクセスすると、プロパティオブジェクトが返されます(これは、__get__メソッドが選択するためです)。しかし、それは慣例です。そのようにする必要はありません。

したがって、クラスにゲッター記述子があれば十分であり、設定しようとすると記述子が上書きされることを気にしない場合は、メタクラスプログラミングなしで次のようなことを行うことができます。

def classproperty_getter_only(f):
    class NonDataDescriptor(object):
        def __get__(self, instance, icls):
            return f(icls)
    return NonDataDescriptor()

class Foo(object):

    @classproperty_getter_only
    def flup(cls):
        return 'hello from', cls

print Foo.flup
print Foo().flup

にとって

('hello from', <class '__main__.Foo'>)
('hello from', <class '__main__.Foo'>)

本格的なデータ記述子が必要な場合、または組み込みのプロパティオブジェクトを使用する場合は、メタクラスを使用してそこに配置できます(この属性は、クラスのインスタンスからは完全に見えないことに注意してください。メタクラスクラスのインスタンスで属性ルックアップを実行する場合は検査されません)。

それはお勧めですか?私はそうは思わない。私はあなたが本番コードで何気なく説明していることをしません。私はそうする非常に説得力のある理由がある場合にのみそれを検討します(そして私は頭のてっぺんからそのようなシナリオを考えることはできません)。メタクラスは非常に強力ですが、すべてのプログラマーに十分に理解されているわけではなく、推論するのがやや難しいため、メタクラスを使用するとコードの保守が難しくなります。この種のデザインは、Pythonコミュニティ全体で眉をひそめるだろうと思います。

于 2010-07-18T21:31:22.190 に答える