鉴于Python文件的源代码,我想检测所有导入的对象。例如,鉴于此来源:
import mymod
from mymod2 import obj1, obj2, obj3
from mymod3 import aobj
我想得到:
[('mymod2', 'obj1', 'obj2', 'obj3'), ('mymod3', 'aobj')]
我已经尝试过这个正则表达式:
r'from (?P<mod>[_\w\d]+) import (?:(?P<obj>[_\w\d]+)[,\s]?)+'
但我只得到第一个导入的对象:
[('mymod2', 'obj1'), ('mymod3', 'aobj')]
答案 0 :(得分:8)
比正则表达式更好的工具是Python附带的ast
模块。要查找from ... import
最外层范围内的所有a.py
语句并打印所有导入的名称,您可以使用
import ast
code = open("a.py").read()
for node in ast.parse(code).body:
if isinstance(node, ast.ImportFrom):
for name in node.names:
print name.name
请注意,这个简单的代码将遗漏任何不直接在模块级别的语句,例如try-block中的import语句。通过使用ast.walk()
遍历所有节点,可以轻松解决此问题。
答案 1 :(得分:2)
使用正则表达式以文本方式处理Python源代码是个坏主意。更好的想法(没有依赖关系)是将它包含在您的脚本中,然后使用Python进行内省:
#-- test.py (the file you're targeting)
from time import asctime
from re import match, search
#-- now to find its imports
>>> import test
>>> for imprt in dir(test):
... imprt = getattr(test, imprt, None)
... if not getattr(imprt, '__module__', None):
... continue
... if imprt.__module__ in result:
... result[imprt.__module__].append(imprt.__name__)
... else:
... result[imprt.__module__] = [imprt.__name__]
...
>>> result
{'re': ['match', 'search'], 'time': ['asctime']}