python编译包说明

python compiler package explain

我苦苦寻找,几乎找不到任何关于如何使用python编译包(https://docs.python.org/2/library/compiler.html) and how to create a Visitor class that can be feed into the compiler.walk(https://docs.python.org/2/library/compiler.html#compiler.walk)方法的信息。

有人可以帮我吗?提前致谢。

您通过定义 compiler.visitor.ASTVisitor 的子 class 然后为您希望访问者访问的每种类型的节点定义一个方法 visitXXX 来创建访问者 class句柄(其中 XXX 是节点类型的名称 - 可能的节点类型列在您链接的文档的 table 中)。

任何此类方法都将采用一个参数(如果算上 self,则为两个),这将是表示被访问节点的节点对象。 table 中还列出了此类对象的可用属性。如果您希望访问者进一步进入树中,您应该在节点的每个子节点上调用 visit

In the compiler.visitor.walk() method, it accepts 2 paramenters, tree and visitor. What are those?

tree 是您要处理的 AST,visitor 是您创建的用于处理该 AST 的访问者 class 的实例。

And how can i obtain those?

您通过在某些 Python 源代码上调用 compiler.parse 获得 AST,您通过编写访问者 class 并创建它的实例来获得访问者。

下面是一个使用访问者的示例,它简单地计算一段 Python 代码中加法运算符的数量:

import compiler

class PlusCounter(compiler.visitor.ASTVisitor):
    def __init__(self):
        self.count = 0

    def visitAdd(self, node):
        self.count += 1
        self.visit(node.left)
        self.visit(node.right)

plus_counter = PlusCounter()
compiler.walk(compiler.parse("1 + 2 * (3 + 4)"), plus_counter)
print(plus_counter.count)

这里是使用未弃用的 ast 包的相同示例,其工作方式基本相同,但 AST 结构略有不同。与上面的代码不同,这个代码实际上可以在 Python 3:

中工作
import ast

class PlusCounter(ast.NodeVisitor):
    def __init__(self):
        self.pluses = 0

    def visit_Add(self, node):
        # We don't need to visit any child nodes here because in the ast package
        # the AST is structured slightly differently and Add is merely a child
        # node of the BinOp node, which holds the operands. So Add itself has
        # no children that need to be visited
        self.pluses += 1

plus_counter = PlusCounter()
plus_counter.visit(ast.parse("1 + 2 * (3 + 4)"))
print(plus_counter.pluses)

由于 compiler 包已弃用,您可能还应该看看 ast package

关于 Python ast 的优秀文档可以在“Green Tree Snakes - The Missing Python AST docs”中找到。 它的一个非常广泛的使用示例是 Transcrypt's Generator class.