Python 3.10不这么认为:
Python 3.10.6 | packaged by conda-forge | (main, Aug 22 2022, 20:38:29) [Clang 13.0.1 ] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from typing import Iterable
>>> isinstance(list[str], Iterable)
False
>>> list(list[str])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'types.GenericAlias' object is not iterable
Python 3.11认为它是:
Python 3.11.0 | packaged by conda-forge | (main, Jan 15 2023, 05:44:48) [Clang 14.0.6 ] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from typing import Iterable
>>> isinstance(list[str], Iterable)
True
>>> list(list[str])
[*list[str]]
如果它是一个可迭代对象,那么对它进行迭代的结果应该是什么?*list[str]
项看起来是它自己的unpacking
,或者是一个类型变量元组的unpacking
。
这是怎么回事呢?我知道python中的输入技术处于不断变化和快速发展的状态,但我真的不知道该如何解释。
更新:修复了3.10示例中的拼写错误,如Daniil Fajnberg所示
3条答案
按热度按时间oyxsuwqo1#
对于Python 3.11,由于
isinstance(list[str], Iterable)
为真,所以答案必须是“是的,list[str]
是一个可迭代对象”,至于“为什么"这个问题,我可能会给予一个技术上的解释,尽管不是一个实际的原因,但作为一个部分答案,这可能还是有帮助的:在Python 3.10和Python 3.11中,
list[str]
都是types.GenericAlias
的一个示例,区别在于后者的签名:在3.11中,types.GenericAlias
提供了一个__iter__()
方法;在3.10中,它没有。例如,我们可以按如下方式检查:
...甚至更短:
在Python 3.10中,这将引发一个
AttributeError
,而在Python 3.11中,它将返回一个<slot wrapper '__iter__' of 'types.GenericAlias' objects>
对象。__iter__()
方法的存在或不存在反过来会使isinstance(list[str], Iterable)
调用的计算结果分别为false(3.10)和true(3.11),如abc.Iterable
所示:选中
isinstance(obj, Iterable)
将检测注册为Iterable
或具有__iter__()
方法的类。至于Python 3.11为什么添加
GenericAlias.__iter__()
,我不知道,很遗憾,快速搜索(包括Python更改日志)没有得到任何结果。m1m5dgzv2#
typing
模块不包含父类--它只支持类型提示(主要由IDE或Linter等使用)。list[str]
是一个可迭代项,您可以使用iter
函数检查它。您可以阅读此答案以了解更多详细信息-https://stackoverflow.com/a/1952481
bpsygsoo3#
不知道把一个类型转换成列表的目的是什么,但是在python 3.9.13中,你可以把一个字符串转换成列表,然后遍历它: