18

次のラッパークラスを作成しました。__setattr__すべての属性をラップされたクラスにリダイレクトするように定義したいと思います。ただし、これにより、ラッパークラスを初期化できなくなります。これを修正するエレガントな方法はありますか?

class Wrapper:
    def __init__(self, value):
        # How to use the default '__setattr__' inside '__init__'?
        self.value = value

    def __setattr__(self, name, value):
        setattr(self.value, name, value)
4

4 に答える 4

18

すべての割り当てをキャッチしているため、コンストラクターがを割り当てることができませんself.valueself.__dict__インスタンスディクショナリにアクセスするために使用できます。試す:

class Wrapper:
    def __init__(self, value):
        self.__dict__['value'] = value

    def __setattr__(self, name, value):
        setattr(self.value, name, value)

を使用する別の方法object.__setattr__

class Wrapper(object):
    def __init__(self, value):
        object.__setattr__(self, 'value', value)

    def __setattr__(self, name, value):
        setattr(self.value, name, value)
于 2012-10-21T15:05:16.710 に答える
11

メソッドの構文__setattr__を変更せずに初期化後までを無効にする方法については、ここで説明します。つまり、初期化の知識をオブジェクトに埋め込み、それをメソッドで使用します。あなたのために:self.value = value__init____setattr__Wrapper

class Wrapper:
    __initialized = False
    def __init__(self, value):
        self.value = value
        self.__initialized = True

    def __setattr__(self, name, value):
        if self.__initialized:
            # your __setattr__ implementation here
        else:
            object.__setattr__(self, name, value)
于 2014-06-20T19:00:01.070 に答える
0

同様に__getattr__オーバーライドされます::

class Wrapper:
    def __init__(self,wrapped):
        self.__dict__['wrapped'] = wrapped
    def __setattr__(self,name,value):
        setattr(self.__dict__['wrapped'],name,value)
    def __getattr__(self,name):
        return getattr(self.__dict__['wrapped'],name)


class A:
    def __init__(self,a):
        self.a = a

wa = Wrapper(A(3))
#wa.a == wa.wrapped.a == 3
于 2016-06-03T13:54:16.673 に答える
0

他の回答で示唆されているように、1つのアイデアは、オブジェクトディクショナリに直接アクセスしてsetattr解決をバイパスすることです。

読みやすいものについては、次のことをお勧めします。

  def __init__(self,wrapped1, wrapped2):
       vars(self).update(dict(
          _wrapped1=wrapped1,
          _wrapped2=wrapped2,
        ))

varsの使用はオプションですが、に直接アクセスするよりも優れていると思いますself.__dict__。インラインdict()表記により、ボイラープレートコードのオーバーヘッドを最小限に抑えて、すべてのインスタンス変数の初期化を可視ブロックにグループ化できます。

于 2019-11-03T01:48:46.857 に答える