简体   繁体   中英

Bind method to object runtime late binding

I am aware about late bindings in loop in python, but I cant find way to solve this .

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()

I tried with partial in functools but not get success :(

When you call a.bar() my_method is invoked and since the for loop has ended the value of method for it is the last element in methods list so you always get "FOO" as result.

To check you can add a print statement:

def my_method():
    print(method.__name__) # this will always print `foo`
    result = method()

But when I set it directly:

def bind_method(object, methods):
    for method in methods:
        setattr(object, method.__name__, method)

It does work.


Using 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))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM