让我们检查一下我们在做不好时收到的错误:
>>> x = 1
>>> f(*x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() argument after * must be a sequence, not int
>>> f(**x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() argument after ** must be a mapping, not int
太好了:所以我们需要* 的序列类型和** 的映射类型。其余部分相当简单:Python 3 docs 状态:
共有三种基本的序列类型:列表、元组和范围对象。专为处理二进制数据和文本字符串而定制的其他序列类型在专用部分中进行了描述。
检查 var 是否为序列类型的故障安全方法是:
>>> import collections
>>> all(isinstance(x, collections.Sequence) for x in [[], (), 'foo', b'bar', range(3)])
True
(请参阅Python: check if an object is a sequence 了解更多信息)
映射类型,根据docs,是dict:
目前只有一种标准映射类型,即字典。
你可以用同样的方式检查这个,使用isinstance,它甚至会处理派生类:
>>> from collections import OrderedDict
>>> from collections import Counter
>>> all(isinstance(x, dict) for x in [{}, OrderedDict(), Counter()])
True
所以你可以这样做:
import collections
if isinstance(x, dict):
foo(**x)
elif isinstance(x, collections.Sequence):
foo(*x)
else:
foo(x)