Monkey-patching bound methods in python
本问题已经有最佳答案,请猛点这里访问。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | >>> class A: ... def foo(self): ... print(self) ... >>> >>> a = A() >>> a.foo() <__main__.A instance at 0x7f4399136cb0> >>> def foo(self): ... print(self) ... >>> a.foo = foo >>> a.foo() Traceback (most recent call last): File"<stdin>", line 1, in <module> TypeError: foo() takes exactly 1 argument (0 given) |
我试着理解猴子在Python中的修补。请说明错误的原因以及如何修复错误。
如本回答中所述,您需要在执行此操作时使用
1 | a.foo = types.MethodType(foo, a) |
原因是
有关更多详细信息,请参阅以上链接的答案。
所以这里的棘手之处在于,你得到的取决于方法所处的位置:
1 2 3 4 5 6 7 8 9 10 11 12 | class A(object): def foo(self): print("Hello world") def patch(self): print("patched!") print(type(A.foo)) a = A() print(type(a.foo)) |
如果运行此命令,在python2.x和3.x上会得到不同的结果:
1 2 3 4 5 6 | $ python ~/sandbox/test.py # python2.x <type 'instancemethod'> <type 'instancemethod'> $ python3 ~/sandbox/test.py # python3.x <class 'function' at 0x100228020> <class 'method' at 0x10021d0c0> |
但在这两种情况下,很明显,
如果我们试着用猴子修补它会发生什么?
1 2 | a.foo = patch print(type(a.foo)) # <type 'function'> (2.x) / <class 'function'> (3.x) |
好,现在我们看到
1 | a.foo = patch.__get__(a, A) |
对于一个类上的方法,当您执行