2016-08-02 14 views
0

Ich suchte hart, konnte aber kaum Informationen finden, wie das Python-Compiler-Paket (https://docs.python.org/2/library/compiler.html) zu verwenden und wie eine Visitor-Klasse erstellen, die in die Compiler.Walk (https://docs.python.org/2/library/compiler.html#compiler.walk) -Methode eingegeben werden kann.Python-Compiler-Paket zu erklären

Kann mir bitte jemand helfen? Danke im Voraus.

+0

Welcher Teil der "[Verwendung von Besuchern zu Fuß ASTs] (https://docs.python.org/2/library/compiler.html#module-compiler.visitor)" gab Ihnen Ärger? –

+0

@ KevinJ.Chase In der Methode compiler.visitor.walk() akzeptiert es 2 Parameter, Baum und Besucher. Was sind diese? Und wie kann ich diese bekommen? – lionel319

+1

Beachten Sie, dass das Compiler-Paket veraltet ist, wie die verknüpfte Dokumentation angibt. Sie sollten stattdessen das 'ast'-Paket verwenden. – sepp2k

Antwort

2

Sie eine Besucher-Klasse erstellen, indem Sie eine Unterklasse von compiler.visitor.ASTVisitor definieren und dann definiert eine Methode visitXXX für jede Art von Knoten, die Sie Ihre Besucher behandeln möchten (wo XXX ist der Name des Knotentypen - die möglichen Typen von Knoten sind aufgeführt in der Tabelle in der Dokumentation, die Sie verknüpft haben).

Jede solche Methode benötigt ein Argument (zwei, wenn Sie self zählen), das das Knotenobjekt darstellt, das den besuchten Knoten darstellt. Die für ein solches Objekt verfügbaren Attribute sind ebenfalls in der Tabelle aufgeführt. Wenn Sie möchten, dass der Besucher weiter in den Baum hineingeht, sollten Sie auf jedem Kindknoten des Knotens visit aufrufen.

In der Compiler.visitor.walk() -Methode akzeptiert es 2 Parameter, Baum und Besucher. Was sind diese?

tree ist die AST, die Sie bearbeiten möchten, und visitor ist eine Instanz des Besuchers Klasse, die Sie, dass AST zu verarbeiten erstellt.

Und wie kann ich diese erhalten?

Sie erhalten die AST durch compiler.parse auf einige Python-Quellcode aufrufen und Sie den Besucher erhalten durch einen Besucher-Klasse zu schreiben und eine Instanz davon zu schaffen.

Hier ist ein Beispiel eines Besucher verwenden, die einfach zählt die Anzahl der Zusatz-Betreiber in einem Stück Python-Code:

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) 

Und hier ist das gleiche Beispiel des Nicht-veraltet ast Paket mit, das funktioniert im Grunde die gleiche Art, aber hat eine etwas andere AST-Struktur. Im Gegensatz zu dem obigen Code, wird dies eine wirklich funktioniert in 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)