有没有一种方法可以用实际来源替换python import?

时间:2019-06-04 13:08:05

标签: python compilation python-import

我有带有import语句的python文件,我想将它们替换为放置在foo.py中的实际代码。

例如,使用in文件:

from foo import Bar

bar = Bar()
print bar

我想在下面out归档:

# source of Bar class.

bar = Bar()
print bar

如何执行此类进口替换?

1 个答案:

答案 0 :(得分:0)

我建议您使用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来编译具有正确的globals和locals dict的源。

注意2 :考虑到您将需要处理嵌套的导入(如果foo文件存储了您希望替换为的导入)。

注意3 :我已经使用astor将代码从ast树转换为python代码。