Я предлагаю вам использовать ast.NodeTransformer для выполнения такой замены импорта.
AST предоставляет способ взаимодействия с кодом Python, как с деревьями грамматики абстрактного синтаксиса Python.
ast.NodeTransformer может использоваться для обхода вашего кода и идентификации узла ImportFrom (код, проанализированный с помощью ast, представлен в виде дерева узлов). После идентификации узла ImportFrom вы можете заменить его группой узлов, которые соответствуют исходному коду класса Bar
класса , который ведет к вашей цели.
Пожалуйста, смотрите код ниже, который описывает подход, описанный ниже:
from ast import NodeTransformer, parse, fix_missing_locations
import astor
class FromImportTransformer(NodeTransformer):
""" General from imports transformer. """
def visit_ImportFrom(self, node):
new_node = self.get_sources(node)
# Replace node.
fix_missing_locations(node)
return node
def get_sources(self, node):
""" Accepts importFrom node and build new ast tree from the sources described in import. """
raise NotImplemented
def transform_imports(self, source_file):
with open(source_file) as original_sources:
sources = original_sources.read()
root = parse(sources, source_file)
try:
root = FromImportTransformer().visit(root)
except Exception as exc:
raise exc
sources = astor.to_source(root, indent_with=' ' * 4, add_line_information=False)
return processed_sources
path_to_in_sources = '/tmp/in.py'
path_to_out_sources = '/tmp/out.py'
processed_sources = transform_imports(path_to_in_sources)
with open(path_to_out_sources, 'wb+') as out:
out.write(processed_sources)
ПРИМЕЧАНИЕ 1 : Я предлагаю вам использовать exec , чтобы скомпилировать источники с правильными глобальными и локальными данными.
ПРИМЕЧАНИЕ 2 : Учтите, что вам нужно будет обрабатывать вложенные операции импорта (если в хранилище файлов foo импортируются файлы, которые вы хотите заменить).
ПРИМЕЧАНИЕ 3 : Я использовал astor для преобразования кода из дерева ast в код Python.