【发布时间】:2019-03-29 15:56:38
【问题描述】:
假设有一个泛型函数:
def fn(*args, **kwargs):
return {"args":args,"kwargs":kwargs}
签名中的星号运算符允许用户使用任意数量的参数调用函数,方法是使用一颗星来“解开”元组,两颗星用于字典。
现在假设我们想多次调用这个函数,其中一些 args 和 kwargs 保持不变,而另一些则在 每次通话。
实现此结果的一种方法是:
result = [fn(*dargs, *args, **dkwargs, **kwargs) for dargs in dynamic_args for dkwargs in dynamic_kwargs]
其中 dynamic_args 可以是任何类型的可迭代对象(包括生成器)
示例:
dynamic_args = [(1, 2, 3), (4, 6, 7), (8, 9, 0)]
dynamic_kwargs = [{"a": "A"}, {"b": "B"}, {"c": "C"}]
args = ("these", "are", "static", "args", )
kwargs = {"static": "kwarg"}
结果:
{'args': (1, 2, 3, 'these', 'are', 'static', 'args'), 'kwargs': {'a': 'A', 'static': 'kwarg'}}
{'args': (1, 2, 3, 'these', 'are', 'static', 'args'), 'kwargs': {'b': 'B', 'static': 'kwarg'}}
{'args': (1, 2, 3, 'these', 'are', 'static', 'args'), 'kwargs': {'c': 'C', 'static': 'kwarg'}}
{'args': (4, 5, 6, 'these', 'are', 'static', 'args'), 'kwargs': {'a': 'A', 'static': 'kwarg'}}
{'args': (4, 5, 6, 'these', 'are', 'static', 'args'), 'kwargs': {'b': 'B', 'static': 'kwarg'}}
{'args': (4, 5, 6, 'these', 'are', 'static', 'args'), 'kwargs': {'c': 'C', 'static': 'kwarg'}}
{'args': (7, 8, 9, 'these', 'are', 'static', 'args'), 'kwargs': {'a': 'A', 'static': 'kwarg'}}
{'args': (7, 9, 0, 'these', 'are', 'static', 'args'), 'kwargs': {'b': 'B', 'static': 'kwarg'}}
{'args': (8, 9, 0, 'these', 'are', 'static', 'args'), 'kwargs': {'c': 'C', 'static': 'kwarg'}}
我认为这是可行的,因为当调用函数获得输入时,*(kw)args 被视为 d(kw)args 的延续,作为单个实体(元组,dict)。
问题是...我的 linter (flake8) 将其视为 InvalidSintax 错误,我是否再次遵循 hacky 的非 Pythonic 路径?
如果是这样,是否有另一种方法可以在不向函数代码添加逻辑并可能保留列表理解语法的情况下获得相同的结果?
【问题讨论】:
-
flake8可能正在使用不允许多次解包的 Python 2 语法分析您的代码。在 Python 3 中完全没问题。 -
对于适用于 Python 2 和 Python 3 的内容,您可以使用
fn(*chain(args, args), **dict(chain(kwargs.items(), dkwargs.items())))。 -
太好了,可能是这样,可能由于某些原因,sublime 中的 mi 配置无法按预期工作。
-
@chepner 你能把它添加为答案吗,你完全正确!
标签: python function parameters