16

Python の装飾システムが大好きです。@propertyを呼び出すときにカスタム コードを実行できる点が気に入っていますaClassObect.attribute。特に、属性を設定するときのデータの検証に。ただし、存在しない属性を設定しようとするときに、カスタム コードを実行する方法が必要ですが、見つけられません。たとえば、次のクラスがあるとします。

class C(object):
    def __init__(self):
        self._x = None

    @property
    def x(self):
        """I'm the 'x' property."""
        return self._x

    @x.setter
    def x(self, value):
        self._x = value

    @x.deleter
    def x(self):
        del self._x

ここで、myObjclass のインスタンスである があり、Cを呼び出すとmyObject.x = 42、データの検証に最適な適切なセッターが実行されます。しかし、これは誰かが を呼び出すのを止めるわけではなくmyOjbect.b = 47、喜んで という新しい属性を作成しますb。新しい属性を設定するときに特別なコードを実行する方法はありますか? 「エラー、この属性は存在しません」などのエラーを発生させる機能が必要です。

4

2 に答える 2

14

Elazarの答えを少し詳しく説明するには、__setattr__マジック メソッドをオーバーライドし、チェックインして、属性が既に存在するかどうかを確認します。そうでない場合は、例外を発生させます。クラスでは次のようになります。

def __setattr__(self, name, value):
    if not hasattr(self, name): # would this create a new attribute?
        raise AttributeError("Creating new attributes is not allowed!")
    super(C, self).__setattr__(name, value)

オーバーライドすることも__getattr____getattribute__存在しない属性のリクエストを処理したい場合も可能ですが、説明した特定の問題については、おそらくこれは必要ありません。

__setattr__上に示した方法は、デリータが原因で、現在のプロパティでうまく機能しないことに注意してください。を削除するmyObj.xと、後でアクセスしようとすると getter が例外を発生させますx。これは、 が既存の属性であるかどうかを確認するとhasattrが返されることを意味するため、再作成することはできません。特定の属性を削除 (および再作成) できるようにする必要がある場合は、より洗練された実装が必要になります (単に に依存するのではなく、目的の名前のプロパティのクラスをチェックインできます)。Falsex__getattr____setattr__hasattr

于 2013-04-26T02:56:25.210 に答える
11

オーバーライド__getattr____setattr__.

于 2013-04-26T02:13:05.440 に答える