模拟将函数参数分配给 *args 和 **kwargs

6

你是否有一种简单的方法来"模拟"将参数分配给函数参数?

假设我有一个函数:

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}
>>> fn(*args, **kwargs)
a=1, b=2, c=3
args=(4,)
kwargs={'extra_kw': 5}

我想提取函数fn中的argskwargs,而不需要调用fn

基本上,我正在尝试编写一个函数,该函数将函数和参数列表以及字典作为输入,并返回额外的argskwargs

def extract_extra_args_and_kwargs(f, *args, **kwargs):
    ...
预期的结果如下所示:
>>> extract_extra_args_and_kwargs(fn, args, kwargs)
((4,), {'extra_kw': 5})

我尝试过使用 inspect.signature,但是由于Python本身必须在某个地方解析此赋值,因此我希望直接访问相应的函数。


也许你已经按照自己的方式完成了它,但你可能希望你的函数是 fn(a, b, *args, c='default', **kwargs) - Stephen C
1
真的,尽管这只是一个没有关系到我的实际代码的基本示例。 - jhansen
2个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
7
这是 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}}
您在问题中定义的extract_extra_args_kwargs将是一个简单的包装器。
def extract_extra_args_kwargs(fn, args, kwargs):
    x = inspect.getcallargs(fn, *args, **kwargs)
    return x['args'], x['kwargs']

太棒了!谢谢 :) - jhansen

7
请注意,根据文档,自Python 3.5起,inspect.getcallargs已被弃用。今后请改用inspect.signature.bind。请注意不要删除HTML标签。
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))
这将输出:
((4,), {'extra_kw': 5})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,