Czy ktoś ma prosty przykład użycia ast.NodeVisitor do przejścia abstrakcyjnego drzewa składni w Pythonie 2.6? Różnica między wizytą a generic_visit jest dla mnie niejasna i nie mogę znaleźć żadnego przykładu za pomocą google codesearch lub zwykłego google.Prosty przykład użycia ast.NodeVisitor?
Odpowiedz
ast.visit
- chyba go nadpisać w podklasie, oczywiście - kiedy nazywa się odwiedzić ast.Node
klasy foo
wzywa self.visit_foo
jeśli ta metoda nie istnieje, w przeciwnym razie self.generic_visit
. Ten drugi, ponownie w swojej implementacji w klasie ast
, po prostu wywołuje na każdym węźle podrzędnym (i nie wykonuje żadnej innej akcji).
więc rozważyć, na przykład:
>>> class v(ast.NodeVisitor):
... def generic_visit(self, node):
... print type(node).__name__
... ast.NodeVisitor.generic_visit(self, node)
...
Tutaj jesteśmy nadrzędnymi generic_visit
wydrukować nazwę klasy, ale również wywołanie do klasy bazowej (tak, że wszystkie dzieci będą również odwiedził). Tak na przykład ...:
>>> x = v()
>>> t = ast.parse('d[x] += v[y, x]')
>>> x.visit(t)
emituje:
Module
AugAssign
Subscript
Name
Load
Index
Name
Load
Store
Add
Subscript
Name
Load
Index
Tuple
Name
Load
Name
Load
Load
Load
Ale załóżmy, że nie dba o węzłach ładunkowych (i jego dzieci - gdyby każdy ;-). Następnie w prosty sposób poradzić sobie z tym może być, na przykład:
>>> class w(v):
... def visit_Load(self, node): pass
...
Teraz, kiedy odwiedzasz węzeł obciążenia, visit
depesze, nie generic_visit
więcej, ale do naszego nowego visit_Load
... co robi” w ogóle zrobić cokolwiek. A więc:
>>> y = w()
>>> y.visit(t)
Module
AugAssign
Subscript
Name
Index
Name
Store
Add
Subscript
Name
Index
Tuple
Name
Name
lub, przypuśćmy, że chcieliśmy zobaczyć rzeczywiste nazwy węzłów Name; następnie ...:
>>> class z(v):
... def visit_Name(self, node): print 'Name:', node.id
...
>>> z().visit(t)
Module
AugAssign
Subscript
Name: d
Index
Name: x
Store
Add
Subscript
Name: v
Index
Tuple
Name: y
Name: x
Load
Load
Ale NodeVisitor jest klasą, ponieważ pozwala jej przechowywać informacje podczas wizyty. Załóżmy, że chcemy tylko zestawu nazw w "module". Wtedy nie musimy przesłonić generic_visit
więcej, ale raczej ...:
>>> class allnames(ast.NodeVisitor):
... def visit_Module(self, node):
... self.names = set()
... self.generic_visit(node)
... print sorted(self.names)
... def visit_Name(self, node):
... self.names.add(node.id)
...
>>> allnames().visit(t)
['d', 'v', 'x', 'y']
Tego rodzaju rzeczy jest więcej niż typowy przypadek użycia tych wymagających przesłonięcia z generic_visit
- normalnie, jesteś tylko zainteresowany w kilku rodzajach węzłów, tak jak jesteśmy tutaj w module i nazwie, więc możemy po prostu przesłonić visit_Module
i visit_Name
i pozwolić ast visit
zrobić wysyłkę w naszym imieniu.
generic_visit
jest wywoływana, gdy nie można znaleźć niestandardowego użytkownika (np. Nazwa_domeny). Oto fragment kodu, który napisałem ostatnio z ast.NodeVisitor: https://github.com/pypy/pypy/blob/master/py/_code/_assertionnew.py Interpretuje węzły AST w celu uzyskania informacji o debugowaniu niektórych z nich i ponownie wraca z generic_visit
, gdy nie jest dostarczana specjalna implementacja.
Patrząc na kod w ast.py nie jest trudno skopiować i wkleić własnego chodzik. Na przykład.
import ast
def str_node(node):
if isinstance(node, ast.AST):
fields = [(name, str_node(val)) for name, val in ast.iter_fields(node) if name not in ('left', 'right')]
rv = '%s(%s' % (node.__class__.__name__, ', '.join('%s=%s' % field for field in fields))
return rv + ')'
else:
return repr(node)
def ast_visit(node, level=0):
print(' ' * level + str_node(node))
for field, value in ast.iter_fields(node):
if isinstance(value, list):
for item in value:
if isinstance(item, ast.AST):
ast_visit(item, level=level+1)
elif isinstance(value, ast.AST):
ast_visit(value, level=level+1)
ast_visit(ast.parse('a + b'))
Drukuje
Module(body=[<_ast.Expr object at 0x02808510>])
Expr(value=BinOp(op=Add()))
BinOp(op=Add())
Name(id='a', ctx=Load())
Load()
Add()
Name(id='b', ctx=Load())
Load()
- 1. prosty przykład użycia require.js
- 2. Prosty przykład użycia procesora w SBCL
- 3. Prosty przykład użycia Erlanga do https post
- 4. Dobry przykład użycia libpurple?
- 5. v4l2 bardzo prosty przykład
- 6. Prosty przykład KVO
- 7. listfragment prosty przykład
- 8. MVC3 DropDownListFor - prosty przykład?
- 9. ReactiveSwift Prosty przykład
- 10. Przykład użycia IF w PHP
- 11. Przykład użycia SetupDiGetDeviceProperty
- 12. Android LocationServices.GeofencingApi przykład użycia
- 13. Przykład użycia Android RtpStream
- 14. WPF - animacja sekwencyjna prosty przykład
- 15. Prosty przykład intencji i pakietu
- 16. OpenLayers 3: prosty przykład LineString
- 17. SQLAlchemy Generic Relationship prosty przykład
- 18. Algorytm wspinaczki górskiej prosty przykład
- 19. Qt: Prosty przykład dla Quazip
- 20. Prosty przykład reifikacji w RDF
- 21. Przykład użycia AutoFixture z NSubstitute
- 22. Przykład użycia LibSVM w java
- 23. Prosty przykład oozie z zapytaniem o ula?
- 24. Bardzo prosty przykład ładowania pliku Silverlight
- 25. prosty przykład node.js w aws lambda
- 26. Jak zbudować bardzo prosty przykład Guard?
- 27. Pokaż mi prosty przykład strumieni Oracle?
- 28. Prosty przykład ArcGIS dynamicznie renderujący znacznik
- 29. Jaki jest prosty przykład asynchronicznej funkcji javascript?
- 30. Prosty przykład PostgreSQL kwerendy w Ruby
Dziękujemy! - właśnie tego szukałem. – lacker
@lacker, nie ma za co! –
Świetne, chciałbym zrozumieć nieco więcej różnic między kompilatorem a ast teraz ... –