如何列出导入的模块?
- 2025-01-13 08:53:00
- admin 原创
- 94
问题描述:
如何枚举所有导入的模块?
例如我想['os', 'sys']
从此代码中获取:
import os
import sys
解决方案 1:
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 as alias
;如果您想要别名,则返回yield name。
解决方案 2:
sys.modules
找到与的交点globals
:
import sys
modulenames = set(sys.modules) & set(globals())
allmodules = [sys.modules[name] for name in modulenames]
解决方案 3:
如果您想从脚本外部执行此操作:
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 加载的所有模块。
解决方案 4:
假设你已经导入了数学和重新:
>>import math,re
现在看到同样的用途
>>print(dir())
如果在导入之前和导入之后运行它,你就会看到差异。
解决方案 5:
print [key for key in locals().keys()
if isinstance(locals()[key], type(sys)) and not key.startswith('__')]
解决方案 6:
它实际上工作得很好:
import sys
mods = [m.__name__ for m in sys.modules.values() if m]
这将创建一个包含可导入模块名称的列表。
解决方案 7:
此代码列出了您的模块导入的模块:
import sys
before = [str(m) for m in sys.modules]
import my_module
after = [str(m) for m in sys.modules]
print [m for m in after if not m in before]
如果您想知道在新系统上安装哪些外部模块来运行您的代码,它应该很有用,而不需要一次又一次地尝试。
它不会列出sys
从中导入的一个或多个模块。
解决方案 8:
这里有很多扭曲的答案,其中一些在最新的 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 (' {}
'.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:我不确定我在这里使用的词汇是否正确,因此如果需要纠正,请发表评论。
解决方案 9:
此处列出的其他答案需要安装导入的模块。我的用例是在加载文件之前检查所需的模块是否已安装。我使用ast
包来实现这一点:
import ast
def dependency_list(filename:str) -> list[str]:
with open(filename,"r") as f:
file_raw = f.read()
# Convert the loaded file into an Abstract Syntax Tree
file_ast = ast.parse(file_raw)
modules = []
# Walk every node in the tree
for node in ast.walk(file_ast):
# If the node is 'import x', then extract the module names
if isinstance(node,ast.Import):
modules.extend([x.name for x in node.names])
# If the node is 'from x import y', then extract the module name
# and check level so we can ignore relative imports
if isinstance(node,ast.ImportFrom) and node.level is None:
modules.append(node.module)
# Get only the parent module for e.g. 'import x.y.z'
# Use set to remove duplicates
return list(set([x.split(".")[0] for x in modules]))
解决方案 10:
从@Lila 窃取(由于没有格式而无法发表评论),这也显示了模块的 /path/:
#!/usr/bin/env python
import sys
from modulefinder import ModuleFinder
finder = ModuleFinder()
# Pass the name of the python file of interest
finder.run_script(sys.argv[1])
# This is what's different from @Lila's script
finder.report()
生成结果:
Name File
---- ----
...
m token /opt/rh/rh-python35/root/usr/lib64/python3.5/token.py
m tokenize /opt/rh/rh-python35/root/usr/lib64/python3.5/tokenize.py
m traceback /opt/rh/rh-python35/root/usr/lib64/python3.5/traceback.py
...
.. 适合用于 grepping 或诸如此类。注意,它很长!
解决方案 11:
在这种情况下,我喜欢使用列表推导:
>>> [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)