将方法绑定到对象运行时后期绑定
Bind method to object runtime late binding
我知道 python 中循环中的后期绑定,但我找不到解决这个问题的方法。
def bind_method(object, methods):
for method in methods:
def my_method():
result = method()
return result
setattr(object, method.__name__, my_method)
def test():
class A: pass
def bar():
return "BAR"
def foo():
return "FOO"
a = A()
bind_method(a, [bar, foo])
assert a.foo() == "FOO"
assert a.bar() == "BAR"
if __name__ == "__main__":
test()
我在 functools
中尝试使用 partial
但没有成功 :(
当你调用 a.bar()
时,my_method
被调用,因为 for 循环已经结束了 method
的值,因为它是 methods
列表中的最后一个元素,所以你结果总是 "FOO"
。
要检查你可以添加打印语句:
def my_method():
print(method.__name__) # this will always print `foo`
result = method()
但是我直接设置的时候:
def bind_method(object, methods):
for method in methods:
setattr(object, method.__name__, method)
确实有效。
使用functools.partial
:
from functools import partial
def bind_method(object, methods):
for method in methods:
def my_method(a_method):
print(a_method.__name__) # this print correct method name
result = a_method()
return result
setattr(object, method.__name__, partial(my_method, method))
我知道 python 中循环中的后期绑定,但我找不到解决这个问题的方法。
def bind_method(object, methods):
for method in methods:
def my_method():
result = method()
return result
setattr(object, method.__name__, my_method)
def test():
class A: pass
def bar():
return "BAR"
def foo():
return "FOO"
a = A()
bind_method(a, [bar, foo])
assert a.foo() == "FOO"
assert a.bar() == "BAR"
if __name__ == "__main__":
test()
我在 functools
中尝试使用 partial
但没有成功 :(
当你调用 a.bar()
时,my_method
被调用,因为 for 循环已经结束了 method
的值,因为它是 methods
列表中的最后一个元素,所以你结果总是 "FOO"
。
要检查你可以添加打印语句:
def my_method():
print(method.__name__) # this will always print `foo`
result = method()
但是我直接设置的时候:
def bind_method(object, methods):
for method in methods:
setattr(object, method.__name__, method)
确实有效。
使用functools.partial
:
from functools import partial
def bind_method(object, methods):
for method in methods:
def my_method(a_method):
print(a_method.__name__) # this print correct method name
result = a_method()
return result
setattr(object, method.__name__, partial(my_method, method))