为什么Python解包运算符使用无序集合

时间:2016-10-28 16:05:54

标签: python python-3.x sequence argument-unpacking

关于解包运算符Python 3 tutorialBuilt-in types通常会说"列表或元组,"而不正确使用的错误消息表示"序列"需要:

*

Python 3' {{3}}文档列出了以下序列类型:

  • 序列类型 - Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:38:48) [MSC v.1900 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> def f(a, b): ... return a / b ... >>> f(*1) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: f() argument after * must be a sequence, not int listtuple
  • 文字序列类型 - range
  • 二进制序列类型 - strbytesbytearray

快速测试:

memoryview

请注意,此处包含 等集合类型(如>>> all(isinstance(x, collections.Sequence) for x in [[], (), range(1), '', b'']) True set)和映射类型(frozenset)。

dict

我的问题:为什么所有可迭代类型(包括>>> any(isinstance(x, collections.Sequence) for x in [set(), {}]) False set)都无法解包?它们不是序列类型,因为上面的dict建议它们应该是,并且在解开位置参数时,无序行为会导致未定义的结果:

TypeError

2 个答案:

答案 0 :(得分:3)

在(至少)Python 3.5.2中不再是这种情况 - 可能被认为是一个问题,并且在一个版本中发生了更改,而不是你正在使用的版本。现在更合适的消息是 iterable 而不是 sequence

请参阅https://bugs.python.org/issue4806

>>> def foo(*args):
...     print(*args)
...
>>> foo(*1)
TypeError: foo() argument after * must be an iterable, not int

答案 1 :(得分:2)

错误消息很可能是一个小错误 * 。在函数调用期间接受任何可迭代的东西;这隐藏在section for Calls in the Python Reference Manual

  

如果函数调用中出现语法*expression,则表达式必须求值为可迭代。来自这些迭代的元素被视为它们是附加的位置参数。

(强调我的)

* @sytech指出,3.5.2中的{{1}}已在Issue 4806中修复,以符合参考手册中的正确措辞。