import ast
def find_last_line(func):
last_line = 0
for n in ast.walk(func):
if isinstance(n, ast.stmt) and n.lineno > last_line:
last_line = n.lineno
return last_line
def find_func(func_name, parse_tree):
for n in ast.iter_child_nodes(parse_tree):
if isinstance(n, ast.FunctionDef) and n.name == func_name:
return n
def read_file(filename):
f = open(filename, 'r')
text = f.read()
f.close()
return text
source = read_file('test_ast.py')
lines = source.split('\n')
p = ast.parse(source)
func_node = find_func('find_func', p)
last_line = find_last_line(func_node)
for l in lines[func_node.lineno-1:last_line]:
print l
Kanske inte världens mest solida kod, men vafan. Funkar det då? Ja, det är väl för i helvete klart att det funkar:
Olsson:testo linusakerlund$ python test_ast.py
def find_func(func_name, parse_tree):
for n in ast.iter_child_nodes(parse_tree):
if isinstance(n, ast.FunctionDef) and n.name == func_name:
return n
Olsson:testo linusakerlund$
Sensmoral: det är trevligt med högnivåspråk ibland.
14 kommentarer:
Meddela Blogger om tvivelaktigt innehåll på den här sidan.
Menade du "Meddela Blogger om otvivelaktigt innehåll på den här sidan"?
Det glädjer mig att du använder Python! :-)
Det gör mig lite ledsen att det där find_last_line-grejset ska behövas. :-(
Det finns någon slags "dump" du kan använda på funktionens objekt, men då får du väl någon slags återskapning och inte hur koden såg ut exakt. Gissar jag. Jag har inte provat. Jag tänker inte heller prova.
Jag förstår inte vad du är ledsen över, och det var jag som var din spökskrivare på kompilator-kursen, så jag tror inte att jag borde behöva förklara för dig varför det ser ut som det gör. Skulle i och för sig inte behöva söka igenom hela trädet, sista uttrycket och dess subträd borde räcka, men in the spirit of KISS (rockgruppen) så gör jag som jag gör.
Nu blev jag kissnödig.
wv: någonslagsdump
vem pratar om mig
Någon slags damp som i serialisering (pickle) ist nicht workensich.
Och det kanske inte var så tydligt, men det här exemplet handlade inte om att skriva ut funktionsdefinitioner, utan om att titta lite på ast. Det slutgiltiga målet är att med hjälp av ast, en syntax-highlighter, en textrendrerare och kanske Core Animation bygga en prototyp av en sådan kod-browser som jag beskrev i ett inlägg för några dagar sedan. Vi får väl se om det blir något.
"Det slutgiltiga målet är att med hjälp av ast, en syntax-highlighter, en textrendrerare och kanske Core Animation bygga en prototyp av en sådan kod-browser som jag beskrev i ett inlägg för några dagar sedan."
it isnt possible lol
lol :(
LantLOLlor!
Meddela Blogger om tvivelaktigt inne-LOL på den här sidan. :)
LOL
[wv: slitr]
Nej, alltså, det som gör mig ledsen — :-( — är inte din kod i sig utan att den behövs, liksom, typ, vore det inte rimligt att func-objektet erbjöd någon slags property eller metod som kunde svara på vilka fysiska kodrader (eller t o m vilket spann av teckenpositioner i källkoden) som dess abstrakta innehåll motsvarar.
Själv har jag en medeltida version av Python (2.5.2, den här modulen kom visst i 2.6) installerad och vågar inte uppgradera då jag för närvarande inte vill riskera att brejka vissa livsnödvändiga grejer. LOL!
Jo, det låter ju rimligt, men av någon anledning finns bara info om rad och offset för början av funktionen.
Skicka en kommentar