Python:使用函数的参数传递函数

时间:2016-03-14 07:12:02

标签: python numpy scipy scikit-learn

我有两个功能:

  1. 我无法改变的图书馆功能说lib_func( func, param1)
    lib_func将函数func和其他参数param1作为参数。

  2. 用户定义的函数user_func

  3. 例如:

    x = 0
    y = 0
    def user_func():
        global x
        global y 
        return sqrt(x*y)
    

    现在的问题是我想在将user_func传递给user_func时将x作为参数传递给lib_func而不是全局变量。

4 个答案:

答案 0 :(得分:1)

您可以使用其他功能

包装user_func()
def parameterized_func(local_x):
    global x
    x = local_x
    return user_func()

然后将新的parameterized_func()功能传递给您的lib_func()。 这不是很好,显然会改变全局x变量。 我建议您查看是否无法更改user_func()功能。

答案 1 :(得分:1)

如果我理解正确的任务,你需要做两件事:

  1. 使用user_func参数创建新函数以包裹x, y

  2. 使用functools.partial通过params

  3. 再获取一个函数

    这里的例子。

    模块user_module.py其中user_func已定义:

    x = 0
    y = 0
    def user_func():
       global x
       global y 
       print('user_func', x, y)
    

    您需要完成工作的模块main.py

    def lib_func(func, param1):
        print('lib_func', param1)
        func()
    
    
    # Create user_func with params:
    import user_module
    
    def new_user_func(x, y):
        user_module.x = x
        user_module.y = y
        user_module.user_func()
    
    
    # Use functools.partial to create user_func with ready params:
    from functools import partial
    
    f = partial(new_user_func, 1, 2)
    lib_func(f, 'param1')
    
    f = partial(new_user_func, 3, 4)
    lib_func(f, 'param1')
    

    此示例的输出:

    lib_func param1
    user_func 1 2
    
    lib_func param1
    user_func 3 4
    

答案 2 :(得分:1)

函数只是一个可以调用的对象,因此使用__call__方法定义类原则上等同于定义函数。至少在你给予的背景下。

所以:

def user_func(x, y, z):
    return anything_with(x, y, z)

相当于:

class user_class(object):
    @staticmethod # staticmethod so that it can be called on the class
    def __call__(x, y, z):
        return anything_with(x, y, z)

目前看来这只是混淆。但是,当您使用预定义属性创建实例并且仅将变量参数指定为call的参数时,就会发生魔力:

class user_class(object):
    def __init__(self, x):
        self.x = x

    def __call__(self, y, z): # No x as parameter!
        return do_anything_with(self.x, y, z) # use the predefined x here

但您需要改变调用lib_func的方式:

x = 0
user_class_instance = user_class(0)
result = lib_func(user_class_instance, param1)

因此,它会重复调用具有不同yz的实例,但x将保持不变

然而,大多数此类lib_func函数允许传递变量参数(例如user_func),例如scipy.optimize.curve_fit

curve_fit(user_func, x, y, [initial_guess_param1, param2, ...])

user_funccurve_fit在内部调用(您不必做任何事情!),例如:

user_func(x, initial_guess_param1, param2, ...)
# Then curve-fit modifies initial_guess_param1, param2, ... and calls it again
user_func(x, initial_guess_param1, param2, ...)
# and again modifies these and calls again
user_func(x, initial_guess_param1, param2, ...)
# ... until it finds a solution

xy已定义,在调用curve_fit时未更改,但initial_guess_param1会在找到最佳curve_fit时更改{{1}}

答案 3 :(得分:-2)

尝试打包user_func并返回lib_func的新函数:

def wrapuserfunc(x):
    user_func.x = x
    return user_func

def user_func():
    if hasattr(user_func, 'x'):
        print user_func.x

lib_func(wrapuserfunc(1), param1)  # user_func.x = 1
# get x in user_func
print user_func.x  # x = 1

wrapuserfunc(x)运行正常。 函数是Python中的对象。