【问题标题】:Dynamically add functions in class在类中动态添加函数
【发布时间】:2019-09-05 07:48:29
【问题描述】:

我正在使用一些变量 (my_name) 在类 (A) 中动态添加函数。但是当我在类(A)中调用函数时,我得到了正确的函数(正确的函数名称),但带有来自最后一个函数的变量。如何在函数中动态设置变量或如何解决这样的问题?

class A:
    pass


function_name_list = ['first/function', 'second/function', 'third/function']


def add_method(cls, fnctname):
    def decorator(func):
        @wraps(func)
        def wrapper(self, *args, **kwargs):
            return func(*args, **kwargs)

        setattr(cls, fnctname, wrapper)
        return func

    return decorator


def create_functions():
    for x in function_name_list:
        name = x.replace('/', '')

        @add_method(A, name)
        def foo(value):
            my_name = copy.deepcopy(name)
            with open('./file' + str(my_name) + '.txt', 'a') as f:
                f.write(str(time.time()) + ',' + my_name + ',' + str(value) + "\n")
                print('Call: ', my_name)


a = A()
create_functions()

for x in function_name_list:
    name = x.replace('/', '')
    getattr(a, '%s' % name)(1)

【问题讨论】:

    标签: python function dynamic


    【解决方案1】:

    在您的create_function 中,def foo() 绑定到变量name。调用该函数时,它将获取name当前 值。只有一个name 变量,因此您的所有foo 函数都绑定到同一个变量。

    如果你真的想这样做,你必须确保每个函数都有一个单独的变量。将for 循环的整个主体拉出到一个单独的函数中,然后它将为每个函数创建不同的变量。

    def create_functions():
        for x in function_name_list:
            create_foo(x.replace('/', ''))
    
    def create_foo(name):
            @add_method(A, name)
            def foo(value):
                with open('./file' + str(name) + '.txt', 'a') as f:
                    f.write(str(time.time()) + ',' + name + ',' + str(value) + "\n")
                    print('Call: ', name)
    

    str 上的copy.deepcopy() 将返回原始的str,因此我将其删除。)

    一个更简单的技术就是使用functools.partial绑定参数:

    import functools
    
    def foo(self, value, name):
        with open('./file' + str(name) + '.txt', 'a') as f:
            f.write(str(time.time()) + ',' + name + ',' + str(value) + "\n")
            print('Call: ', name)
    
    def create_functions():
        for x in function_name_list:
            name = x.replace('/', ''))
            setattr(A, name, functools.partial(foo, name=name))
    

    【讨论】:

      猜你喜欢
      • 2016-06-15
      • 1970-01-01
      • 1970-01-01
      • 2019-09-23
      • 1970-01-01
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      • 2011-02-16
      相关资源
      最近更新 更多