检测导入的对象

2024-06-23 03:16:18 发布

您现在位置:Python中文网/ 问答频道 /正文

给定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')]

Tags: 文件对象fromimportmodobj源代码来源
2条回答

使用regex对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']}

比正则表达式更好的工具是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块中的import语句。通过使用ast.walk()遍历所有节点,可以很容易地解决这个问题。你知道吗

相关问题 更多 >

    热门问题