Учитывая исходный код файла 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')]
Лучшим инструментом, чем регулярные выражения, является модуль ast
, который поставляется с Python. Чтобы найти все операторы 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. Это можно легко устранить, используя ast.walk()
для перемещения по всем узлам.
Это плохая идея для текстовой обработки источника Python с использованием регулярных выражений. Лучшая идея (без зависимостей) заключается в том, чтобы включить ее в ваш script, затем наследовать с помощью 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']}