首页 > 解决方案 > 将一个函数传递给另一个函数,其中内部函数可以访问较大函数 python 中的变量

问题描述

我有一个库函数,用户可以将他们自己的函数传递给该函数,该函数将在库函数执行期间的各个点执行。有时,这些用户函数可能想要访问(而不是修改)仅存在于库函数中的变量。这是当前的实现:

def lib_func(user_func=None):
    lib_var1 = 'somevalue'
    lib_var2 = 'othervalue'
    ...
    if user_func: user_func(lib_var1,lib_var2)
    ...
    if user_func: user_func(lib_var1,lib_var2)

问题是有时用户的函数可能不需要lib_var1or lib_var2,而目前他们仍然需要将它们写为参数:

def my_func(a,b):
    <some-code-not-involving-a-or-b>

lib_func(my_func)

有没有更好的方法来处理用户不需要在他们的函数中包含不必要的参数的这种情况?

标签: pythonfunctionscope

解决方案


一种方法是针对不同的上下文要求不同的函数。如果在某些情况下某些参数未传递给函数,则该函数在该上下文中没有相同的角色。

问问自己该功能在这两种情况下是否具有相同的作用,如果它可能不需要多个功能。

def lib_func(fun_context1=None, fun_context2=None):
    # case with all arguments
    if fun_context1:
        fun_context1(lib_var1, lib_var2)
    
    # specialized case with only one argument
    if fun_context2:
        fun_context2(lib_var1)

# User's function
def my_func1(foo, bar):
    ...

def my_func2(foo):
    ...


lib_func(my_func1, my_func2)

上述解决方案在一定程度上有效......可能存在大量不切实际的特殊情况。如果是这样,您可以要求用户提供一个带**kwargs参数的函数。这将使用户的函数能够灵活地检查传递给它的参数以及在每种情况下要做什么。

def lib_func(user_func=None):
    if user_func:
        user_func(lib_var1=lib_var1, lib_var2=lib_var2)
    
    # case with only one parameters
    if user_func:
        user_func(lib_var1=lib_var1)

# User's function
def my_func(**params):
    lib_var1 = params.get("lib_var1")
    lib_var2 = params.get("lib_var2")

lib_func(my_func)

这种方法的另一个好处是可维护性。如果您的库曾经为用户定义的函数提供额外的关键字参数,这不会破坏用户的代码。


推荐阅读