65

次のように呼び出すことができるreadandメソッドを含むクラスを定義したいと思います。write

instance.read
instance.write
instance.device.read
instance.device.write

インターレースされたクラスを使用しないために、私の考えは__getattr____setattr__メソッドを上書きし、指定された名前がdeviceリターンを にリダイレクトするかどうかを確認することでしたself。しかし、無限再帰を与える問題に遭遇しました。コード例は次のとおりです。

class MyTest(object):
    def __init__(self, x):
        self.x = x

    def __setattr__(self, name, value):
        if name=="device":
            print "device test"
        else:
            setattr(self, name, value)

test = MyTest(1)

コードで__init__新しい attribute を作成しようとすると、xが呼び出さ__setattr__れ、再び が呼び出さ__setattr__れます。このコードを変更するにはどうすればよいですか。この場合、値を保持する の新しい属性xself作成されます1

instance.device.readまたは、「マップ」されるような呼び出しを処理するより良い方法はありますinstance.readか?

理由については常に疑問があります。xmlrpc呼び出しの抽象化を作成する必要があるため、非常に簡単なメソッドなどmyxmlrpc.instance,device.readを作成できます。このようなマルチドットメソッド呼び出しを模倣するには、これを「モック」する必要があります。

4

5 に答える 5

29

self.__dict__または、内部から変更できます__setattr__()

class SomeClass(object):

    def __setattr__(self, name, value):
        print(name, value)
        self.__dict__[name] = value

    def __init__(self, attr1, attr2):
        self.attr1 = attr1
        self.attr2 = attr2


sc = SomeClass(attr1=1, attr2=2)

sc.attr1 = 3
于 2014-08-07T10:21:04.573 に答える
3

設定できる属性と設定できない属性を指定したくない場合は、クラスを分割して、初期化後まで get/set フックを遅らせることができます。

class MyTest(object):
    def __init__(self, x):
        self.x = x
        self.__class__ = _MyTestWithHooks

class _MyTestWithHooks(MyTest):
    def __setattr__(self, name, value):
        ...
    def __getattr__(self, name):
        ...

if __name__ == '__main__':
    a = MyTest(12)
    ...

コードに示されているように、_MyTestWithHooks をインスタンス化すると、以前と同じ無限再帰の問題が発生するため、MyTest をインスタンス化する必要があります。

于 2020-06-03T13:01:18.060 に答える