我建议您使用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 代码。