Wrapper class in Python [duplicate]
Asked Answered
G

1

6

I want to have a wrapper class that behaves exactly like the object it wraps except that it adds or overwrites a few select methods.

My code currently looks like this:

# Create a wrapper class that equips instances with specified functions
def equipWith(**methods):

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

    def __setattr__(self, name, value):
      object.__setattr__(object.__getattribute__(self,'instance'), name, value)

    def __getattribute__(self, name):
      instance = object.__getattribute__(self, 'instance')

      # If this is a wrapped method, return a bound method
      if name in methods: return (lambda *args, **kargs: methods[name](self,*args,**kargs))

      # Otherwise, just return attribute of instance
      return instance.__getattribute__(name)

  return Wrapper

In order to test this out I wrote:

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

a = A(10)
W = equipWith(__add__ = (lambda self, other: self.a + other.a))
b = W(a)
b.a = 12
print(a.a)
print(b.__add__(b))
print(b + b)

When on the last line, my interpreter complains:

Traceback (most recent call last):
  File "metax.py", line 39, in <module>
    print(b + b)
TypeError: unsupported operand type(s) for +: 'Wrapper' and 'Wrapper'

Why is this? How can I get my wrapper class to behave the way I want it to?

Greatcoat answered 8/2, 2013 at 4:47 Comment(2)
#1472 I think this might also be part of the problem.Taproot
This problem looks like one typically solved by metaclasses.Eras
T
7

It looks like what you want can only be done with new-style object with extraordinary measures. see https://mcmap.net/q/219959/-how-can-i-intercept-calls-to-python-39-s-quot-magic-quot-methods-in-new-style-classes, this blog post and the documentation.

Basically, the 'special' functions short-circuit the look-up procedure on new-style objects.

Taproot answered 8/2, 2013 at 5:45 Comment(2)
What do you think is wrong with the top answer on #9058169Thyroid
updated with that link. Definitely did not know meta-classes when I answered this!Taproot

© 2022 - 2024 — McMap. All rights reserved.