【问题标题】:Is there are a way to replace python import with actual sources?有没有办法用实际来源替换 python 导入?
【发布时间】:2019-06-04 13:08:05
【问题描述】:

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

例如,in 文件:

from foo import Bar

bar = Bar()
print bar

我想out下面的文件:

# source of Bar class.

bar = Bar()
print bar

如何执行此类导入替换?

【问题讨论】:

    标签: python compilation python-import


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 2018-12-16
      • 1970-01-01
      • 1970-01-01
      • 2018-09-23
      • 2017-08-01
      • 2011-06-07
      • 2011-08-09
      • 1970-01-01
      相关资源
      最近更新 更多