有没有一种方法可以用实际来源替换python import? [英] Is there are a way to replace python import with actual sources?

查看:146
本文介绍了有没有一种方法可以用实际来源替换python import?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am having python files with the import statements which I would like to replace into the actual code placed in the foo.py.

例如,用文件中:

from foo import Bar

bar = Bar()
print bar

我想在下面的文件中:

I would like to out file below:

# source of Bar class.

bar = Bar()
print bar

如何我执行此类导入替换吗?

How can I perform such imports replacement ?

推荐答案

我建议您使用 ast.NodeTransformer ,以完成此类导入替换。

I suggest you to use the ast.NodeTransformer in order to accomplish such import replacement.

AST 提供了与python代码进行交互的方式

AST provides way to interact with the python code as with the trees of the Python abstract syntax grammar.

ast.NodeTransformer 可用于遍历您的代码并标识 ImportFrom 节点(用ast解析的代码表示为节点树)。确定 ImportFrom 节点后,您可以将其替换为组对应于 Bar 类的源代码的节点,它可以达到您的目标。

The ast.NodeTransformer can be used to traverse through your code and identifying ImportFrom node ( the code parsed with ast is represented as the tree of nodes). After identifying ImportFrom node you can replace it with group of nodes which correspond to the source code of the Bar class, which lead to your goal.

请参见下面的代码,其中描述了以下描述的方法:

Please see code below which describes approach described below:

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 为了使用正确的全局变量和局部变量来编译源。

NOTE 1: I suggest you to use the exec in order to compile sources with correct globals and locals dict.

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

NOTE 2: Take into account that you will need to handle nested imports ( if foo file stores imports you wish to replace to).

注意3 :我使用了 astor 将ast树中的代码转换为python代码。

NOTE 3: I've used astor to convert code from ast tree into the python code.

这篇关于有没有一种方法可以用实际来源替换python import?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆