Checking if a variable can be unpacked
假设我有一个变量
如果
是否有一种简单的方法来检查类型是否可以通过**或*?
我目前正在做的是检查x的类型并执行如下操作:
1 2 3 4 5 6 | if type(x) == 'dict': foo(**x) elif type(x) in ['tuple','list', ...]: foo(*x) else: foo(x) |
但问题是,我不知道实际可以解包的数据类型的完整列表,我也不确定用户定义的数据类型是否可以有一个允许解包的方法。
您可以使用
1 2 3 4 5 6 7 | try: foo(**x) except: try: foo(*x) except: foo(x) |
它是一种粗糙的类型,不区分异常发生的原因(可以通过检查异常类型来减轻),但消除了尝试并枚举可以以何种方式调用的类型的需要。
让我们检查一下在做得不好时收到的错误:
1 2 3 4 5 6 7 8 9 | >>> 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 |
号
太好了:所以我们需要一个用于
There are three basic sequence types: lists, tuples, and range objects. Additional sequence types tailored for processing of binary data and text strings are described in dedicated sections.
号
检查var是否为序列类型的故障安全方法是:
1 2 3 | >>> import collections >>> all(isinstance(x, collections.Sequence) for x in [[], (), 'foo', b'bar', range(3)]) True |
(有关详细信息,请参见python:检查对象是否为序列)
根据文档,映射类型为
There is currently only one standard mapping type, the dictionary.
号
您可以用同样的方法检查它,使用
1 2 3 4 | >>> from collections import OrderedDict >>> from collections import Counter >>> all(isinstance(x, dict) for x in [{}, OrderedDict(), Counter()]) True |
。
所以你可以这样做:
1 2 3 4 5 6 7 | import collections if isinstance(x, dict): foo(**x) elif isinstance(x, collections.Sequence): foo(*x) else: foo(x) |