关于python:保持函数调用签名对于接受另一个函数参数的超集的函数是一致的

Keeping function call signatures consistent for a function that accepts a superset of another function's arguments

我有一个函数(foo),它是另一个函数(bar)的便利函数包装器。 foo调用bar,然后在输出上执行另外两个任务。例如:

1
2
3
4
5
6
7
def bar(bar_arg, bar_kw=None):
    #do some stuff
    return ret

def foo(bar_arg, foo_arg, bar_kw=None, foo_kw=None):
    ret = bar(bar_arg, bar_kw)
    ret.some_method(foo_arg, foo_kw=foo_kw)

我希望foo的调用签名包含来自bar的关键字和参数,以便用户检查foo知道它们可以传递什么,但是,我想避免自己维护完整的参数列表,因为< x1>随着它来自的包更新并且其参数列表很长而趋于改变。由于foo始终使用bar接受的参数和关键字的完整列表调用bar,因此我不认为我应该自己维护列表。

有没有办法根据bar的调用签名为foo构建调用签名?另外,有没有办法捕获字典或命名空间中foo的输入,以便我可以轻松地将foo使用的参数和关键字与bar使用的参数和关键字分开?

注意,我知道* args和** kwargs。但是,它们使函数签名不明确,并且不会通知用户允许哪些参数和关键字参数。

编辑:我应该注意我的用例比这个例子复杂得多。被调用的外部函数(bar)是matplotlib.colorbar.ColorbarBase。调用函数(foo)是绘图类的类方法,该类在我自己的许多应用程序中使用,其他应用程序可能在将来使用。 foo创建一个颜色条,然后根据ColorbarBase不接受的其他参数和关键字对颜色条执行其他工作。


由于bar()包装foo()调用ColorbarBase构造函数,因此在foo()调用周围编写一个装饰器。装饰器在调用foo()之前对传入bar的参数进行修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from matplotlib import pyplot
import matplotlib as mpl


def bar(f):
    def wrapper(*args, **kwargs):
        # Change args, kwargs for calling foo()
        f(*new_args,**new_kwargs)
        return
return wrapper


@bar
def foo(*new_args, **new_kwargs):
    return mpl.colorbar.ColorbarBase(*new_args, **new_kwargs)

例如,以下命令将ColorbarBase对象返回给调用者,给出一组初始参数,然后由bar()修改。以这种方式,foo()的呼叫签名基于bar()的呼叫签名。

1
2
3
4
5
6
7
8
9
fig = pyplot.figure(figsize=(8, 3))
ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15])
cmap = mpl.cm.cool
norm = mpl.colors.Normalize(vmin=5, vmax=10)

ret = foo(ax1,
          cmap=cmap,
          norm=norm,
          orientation='horizontal')

我认为最好的选择是忽略foo。只需使用用户需要的简单构建块,即可让API简短而甜蜜,以便他们快速了解如何使用您的库。程序员可以非常轻松地创建他们真正想要的便利功能,而不会被您认为他们想要的功能分散注意力。

如果您的实际功能比他们在问题中看起来更复杂,那么请更新问题以显示该问题。现在,程序员只需编写即可明确而明确

1
2
my_bar = bar(bar_arg, bar_kw)
my_bar.some_method(foo_arg, foo_kw=foo_kw)

为了自己。任何读者都知道发生了什么,并且不必解析长参数列表,额外的代码行也没问题。