我有一个函数(foo
),它是另一个函数(bar
)的便利函数包装器。 foo
调用bar
,然后在输出上执行另外几项任务。例如:
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
的用户知道他们可以通过什么,但是,我想避免自bar
因为它来自的包更新并且其参数列表很长而导致foo
趋于改变时,我自己维护完整的参数列表。由于bar
始终使用bar
接受的参数和关键字的完整列表来调用foo
,因此我不会发现我应该自己维护列表。
有没有办法根据bar
的呼叫签名为foo
建立呼叫签名?另外,有没有办法捕获字典或命名空间中foo
的输入,以便我可以轻松地将bar
使用的参数和关键字与bar
使用的参数和关键字分开?
注意,我知道* args和** kwargs。但是,它们使函数签名不明确,并且不会告知用户允许哪些参数和关键字参数。
编辑:我应该注意,我的用例比这个例子复杂得多。被调用的外部函数(matplotlib.colorbar.ColorbarBase
)是foo
。调用函数(foo
)是绘图类的类方法,该类在我自己的许多应用程序中使用,其他应用程序可能在将来使用。 ColorbarBase
创建一个颜色条,然后根据C
不接受的其他参数和关键字对颜色条执行其他工作。
答案 0 :(得分:1)
由于bar()
包裹调用foo()
构造函数的ColorbarBase
,因此请在foo()
调用周围编写一个装饰器。装饰器在调用foo()
之前对传入bar的参数进行修改。
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()
的呼叫签名。
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')
答案 1 :(得分:0)
我认为最好的选择是省略foo
。只需使用用户需要的简单构建块,即可让API简短而甜蜜,以便他们快速了解如何使用您的库。程序员可以很容易地创建他们真正想要的便利功能,而不会被你认为他们想要的功能分散注意力。
如果您的实际功能比他们在问题中看起来更复杂,那么请更新问题以显示该问题。现在,程序员只需编写
即可明确而明确my_bar = bar(bar_arg, bar_kw)
my_bar.some_method(foo_arg, foo_kw=foo_kw)
为自己。任何读者都知道究竟发生了什么,并且不必解析长参数列表,并且额外的代码行也没问题。