Python:将带有参数的函数传递给函数



我有两个函数:

  1. 我无法更改的库功能说lib_func( func, param1)
    lib_func将函数func和一些其他参数param1作为参数。

  2. 用户自定义函数user_func

例如:

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

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

函数只是一个可以调用的对象,因此使用 __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_func将由内部curve_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时不会更改,但在找到最佳curve_fit initial_guess_param1时会更改.

你可以用另一个函数包装你的user_func()

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

然后将新的parameterized_func()函数传递给您的lib_func()。这不是很好,并且显然会更改全局x变量。我建议调查一下,看看你是否不能改变user_func()函数。

如果我正确理解了任务,您将需要两件事:

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

  2. 使用
  3. functools.partial 使用传递的参数再获取一个函数

下面是示例。

定义user_func的模块user_module.py

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

尝试包装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 中的对象。

相关内容

  • 没有找到相关文章