如何枚举所有导入的模块?

例如,我想从下面的代码中获取['os', 'sys']:

import os
import sys

当前回答

这里有很多扭曲的答案,其中一些在最新的Python 3.10中不能正常工作。获得脚本完全导入的模块,而不是内部__builtins__或子导入的最佳解决方案是使用以下方法:

# import os, sys, time, rlcompleter, readline
from types import ModuleType as MT
all = [k for k,v in globals().items() if type(v) is MT and not k.startswith('__')]
", ".join(all)

# 'os, sys, time, rlcompleter, readline'

上面的结果是受到@marcin的启发,它基本上是所有模块和全局变量的并集:

# import os, sys, time, rlcompleter, readline
modulenames = set(sys.modules) & set(globals())
allmodules = [sys.modules[name] for name in modulenames]
for i in allmodules: print (' {}\n'.format(i))

#<module 'time' (built-in)>
#<module 'os' from 'C:\\Python310\\lib\\os.py'>
#<module 'sys' (built-in)>
#<module 'readline' from 'C:\\Python310\\lib\\site-packages\\readline.py'>
#<module 'rlcompleter' from 'C:\\Python310\\lib\\rlcompleter.py'>

还要注意,导入的顺序也反映在第一个解决方案中,但没有反映在最后一个解决方案中。然而,在第二个解决方案中也给出了模块路径,这可能在调试中很有用。

PS.我不确定我在这里使用的词汇是正确的,所以如果我需要纠正,请做出评论。

其他回答

如果你想在脚本之外做这个:

Python 2

from modulefinder import ModuleFinder
finder = ModuleFinder()
finder.run_script("myscript.py")
for name, mod in finder.modules.iteritems():
    print name

Python 3

from modulefinder import ModuleFinder
finder = ModuleFinder()
finder.run_script("myscript.py")
for name, mod in finder.modules.items():
    print(name)

这将打印myscript.py加载的所有模块。

在这种情况下,我喜欢使用列表理解:

>>> [w for w in dir() if w == 'datetime' or w == 'sqlite3']
['datetime', 'sqlite3']

# To count modules of interest...
>>> count = [w for w in dir() if w == 'datetime' or w == 'sqlite3']
>>> len(count)
2

# To count all installed modules...
>>> count = dir()
>>> len(count)
print [key for key in locals().keys()
       if isinstance(locals()[key], type(sys)) and not key.startswith('__')]
import sys
sys.modules.keys()

只获取当前模块的所有导入的近似方法是检查模块的globals():

import types
def imports():
    for name, val in globals().items():
        if isinstance(val, types.ModuleType):
            yield val.__name__

它不会返回本地导入,也不会返回像from x import y这样的非模块导入。请注意,它返回val.__name__,因此如果你使用import module作为别名,你会得到原始的模块名;如果需要别名,则生成名称。

这里有很多扭曲的答案,其中一些在最新的Python 3.10中不能正常工作。获得脚本完全导入的模块,而不是内部__builtins__或子导入的最佳解决方案是使用以下方法:

# import os, sys, time, rlcompleter, readline
from types import ModuleType as MT
all = [k for k,v in globals().items() if type(v) is MT and not k.startswith('__')]
", ".join(all)

# 'os, sys, time, rlcompleter, readline'

上面的结果是受到@marcin的启发,它基本上是所有模块和全局变量的并集:

# import os, sys, time, rlcompleter, readline
modulenames = set(sys.modules) & set(globals())
allmodules = [sys.modules[name] for name in modulenames]
for i in allmodules: print (' {}\n'.format(i))

#<module 'time' (built-in)>
#<module 'os' from 'C:\\Python310\\lib\\os.py'>
#<module 'sys' (built-in)>
#<module 'readline' from 'C:\\Python310\\lib\\site-packages\\readline.py'>
#<module 'rlcompleter' from 'C:\\Python310\\lib\\rlcompleter.py'>

还要注意,导入的顺序也反映在第一个解决方案中,但没有反映在最后一个解决方案中。然而,在第二个解决方案中也给出了模块路径,这可能在调试中很有用。

PS.我不确定我在这里使用的词汇是正确的,所以如果我需要纠正,请做出评论。