检测导入的对象

时间:2011-04-19 16:29:52

标签: python regex

鉴于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')]

2 个答案:

答案 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']}