有没有一种简单的方法可以“模拟”参数对函数参数的分配?
说我有一个功能
def fn(a, b, c='default', *args, **kwargs):
print(f'a={a}, b={b}, c={c}')
print(f'args={args}')
print(f'kwargs={kwargs}')
Run Code Online (Sandbox Code Playgroud)
我用以下方式称呼它:
>>> args = (1, 2, 3, 4)
>>> kwargs = {'extra_kw': 5}
>>> fn(*args, **kwargs)
a=1, b=2, c=3
args=(4,)
kwargs={'extra_kw': 5}
Run Code Online (Sandbox Code Playgroud)
我想提取什么args并将kwargs在函数中fn,而无需调用fn。
基本上,我试图编写一个函数,该函数将一个函数以及一个参数列表和字典作为输入,并返回多余的args和kwargs:
def extract_extra_args_and_kwargs(f, *args, **kwargs):
...
Run Code Online (Sandbox Code Playgroud)
该示例的预期结果将是:
>>> extract_extra_args_and_kwargs(fn, args, kwargs)
((4,), {'extra_kw': 5})
Run Code Online (Sandbox Code Playgroud)
我尝试过使用inspect.signature,但是考虑到Python本身必须在某个地方解决此分配问题,所以我希望可以直接访问相应的函数。
这是inspect.getcallargs:
>>> import inspect
>>> def fn(a, b, c='default', *args, **kwargs):
... pass
...
>>> inspect.getcallargs(fn, 1,2,3,4, extra_kw=5)
{'a': 1, 'b': 2, 'c': 3, 'args': (4,), 'kwargs': {'extra_kw': 5}}
Run Code Online (Sandbox Code Playgroud)
您extract_extra_args_kwargs在问题中定义的将是一个简单的包装器。
def extract_extra_args_kwargs(fn, args, kwargs):
x = inspect.getcallargs(fn, *args, **kwargs)
return x['args'], x['kwargs']
Run Code Online (Sandbox Code Playgroud)
请注意,inspect.getcallargs自从Python 3.5开始,每个文档都已弃用。
使用inspect.signature.bind代替前进:
from inspect import signature
def extract_extra_args_and_kwargs(f, *args, **kwargs):
sig = signature(f)
bound = sig.bind(*args, **kwargs)
return bound.arguments['args'], bound.arguments['kwargs']
def fn(a, b, c='default', *args, **kwargs):
print(f'a={a}, b={b}, c={c}')
print(f'args={args}')
print(f'kwargs={kwargs}')
args = (1, 2, 3, 4)
kwargs = {'extra_kw': 5}
print(extract_extra_args_and_kwargs(fn, *args, **kwargs))
Run Code Online (Sandbox Code Playgroud)
输出:
((4,), {'extra_kw': 5})
Run Code Online (Sandbox Code Playgroud)