我正在做一個包裝對象,將採取任意類的實例,然後自動包裝所有的它自己的魔術方法簡單地使用包裝對象的魔術方法(和值)。出於某種原因,這不起作用:爲什麼我不能忽略這種魔法?
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
我想,也許部分沒有與該類型的方法和實例方法之間的區別正常工作,但是當我直接打電話給我的包裝的魔法加,它正常工作。 (這在CPython的3.3測試)
你不能設置情況下的特殊方法,他們總是擡頭的類型。 –
嗯。你是對的。我嘗試了一個類似的例子,除非我直接調用魔術方法,否則cpython會完全忽略它。你知道這是否在語言參考的某個地方嗎? (這是設計決定還是實現細節?)這個約束是否適用於所有實現? – marky1991
看到我的答案,這是一個設計決定。 –