检查我在脚本中导入的不同模块(Python 2或3),并打印其名称。我目前正在使用Python 2.7.12和3.6.4。
该脚本只是导入模块,使用列表理解来查找其中的内容,并打印一个列表:
#!/usr/bin/env python
import sys
import os
import types
module_list = [i.__name__ for i in globals().values()
if type(i) == types.ModuleType and i in sys.modules.values()]
print(module_list)
我最初在Python 3中运行它,它运行得很好(对于Python 2也很好)。输出是:
['__builtin__', 'sys', 'os', 'types'] # Python 2.
['builtins', 'sys', 'os', 'types'] # Python 3.
此时,我决定扩展列表理解,因为我发现它是解密代码/逻辑流程的好习惯。所以我将单个语句替换为:
module_list = []
for i in globals().values():
if type(i) == types.ModuleType and i in sys.modules.values():
module_list.append(i.__name__)
这里的事情变得毛茸茸。我得到一个RuntimeError
,输出现在是:
...
for i in globals().values():
RuntimeError: dictionary changed size during iteration
然而,它仍适用于Python 2 。我现在比其他任何事都更好奇,并尝试了一些事情。
将globals().values()
变为列表:
for i in list(globals().values()):
if type(i) == types.ModuleType and i in sys.modules.values():
module_list.append(i.__name__)
这适用于Python 2或3。
删除了list()
并添加了正确的main
结构:
def main():
module_list = []
for i in globals().values():
if type(i) == type(sys) and i in sys.modules.values():
module_list.append(i.__name__)
print(module_list)
if __name__ == '__main__':
main()
这适用于Python 2和3。
for
循环仅适用于Python 2。list
适用于Python 2和3。main
结构适用于Python 2和3。 Python 3中for
循环破坏了什么呢?
答案 0 :(得分:1)
for i in globals().values():
迭代器后, i
- values
被添加到全局命名空间。如果您在循环之前放置i = None
,或执行for i in list(globals().values()):
,则可以正常工作。
在python 2中,values()
返回一个值列表,但在python 3中它是一个迭代器。迭代器检测到更改并引发错误。