I was working on making a wrapper object that would take an instance of an arbitrary class and then automatically wrap all of its own magic methods to simply use the magic method (and value) of the wrapped object. For some reason, this doesn't work:
class Wrapper:
def __init__(self, wrapped):
self.wrapped = wrapped
for method in filter(lambda x: x.startswith("__") and (x not in
["__init__", "__new__", "__class__", "__metaclass__"]),
dir(wrapped)):
if hasattr(getattr(wrapped, method), "__call__"):
new_func = functools.partial(getattr(type(wrapped), method), self.wrapped)
setattr(self, method, new_func)
t = Wrapper(7)
t + 8
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'Wrapper' and 'int'
class Tester:
def __init__(self):
self.v = 5
def __add__(self, other):
return self.v + other
y = Tester()
y + 7
12
t = Wrapper(y)
t + 9
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'Wrapper' and 'int'
9 + t
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'Wrapper'
t.__add__
functools.partial(<function Tester.__add__ at 0x7fbec6372170>, <__main__.Tester object at 0x7fbec6392990>)
t.__add__(7)
12
I thought maybe the partial wasn't working properly with the distinction between the type's method and an instance method, but when I directly call my wrapper's magic add, it works properly. (This is tested in CPython 3.3)
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…