0

ラップされたオブジェクトとまったく同じように動作するラッパー クラスを作成したいと考えています (いくつかの特定の例外があります)。私が現在抱えている問題は、組み込み関数にあります。組み込み関数をラップされたオブジェクトにリダイレクトするにはどうすればよいですか?

class Wrapper:
    def __init__(self, wrapped):
        object.__setattr__(self, '_wrapped', wrapped)
    def __getattr__(self, name):
        return getattr(object.__getattribute__(self, '_wrapped'), name)

class Foo:
    def __init__(self, val):
        self.val = val
    def __abs__(self):
        return abs(self.val)

foo = Wrapper(Foo(-1))
print(foo.val) # Okay
print(abs(foo)) # TypeError: bad operand type for abs(): 'Wrapper'
4

1 に答える 1

3

Wrapperとの両方のサブクラスである新しいクラスを動的に作成できるため、Foo必要なすべてのプロパティが得られます。

class Wrapper:
    def __new__(self, wrapped):
        cls = type(wrapped)
        new_type = type(cls.__name__ + '_wrapped', (Wrapper, cls), {})
        return object.__new__(new_type)

    def __init__(self, wrapped):
        self._wrapped = wrapped
    def __getattr__(self, name):
        return getattr(self._wrapped, name)

だから今、あなたはできる:

>>> foo = Wrapper(Foo(-1))
>>> abs(foo)
1
>>> type(foo)
<class '__main__.Foo_wrapped'>

PS:

  • この属性を取得および設定するために、および関数にobject.__getattr__(または__setattr__)は必要ありません。__init____getattr__
  • 新しいオブジェクトごとに新しいクラスを作成しないように、この操作をキャッシュすることができます。
于 2012-10-21T20:37:42.950 に答える