2011-08-15 15 views
9

Eksperymentowałem z AST w pytonie. Chcę zmodyfikować metody, transformując AST w czasie wykonywania.Skompiluj pytona AST do metody

Mogę uzyskać źródło wstępnie skompilowanej metody przy użyciu inspect.getsource() i Mogę zmodyfikować AST zgodnie z wymaganiami, używając odwiedzających AST.

To chyba dość naiwny, ale chciałbym, aby móc skompilować AST i zrobić coś podobnego do:

myClass.method.__func__.__code__ = compile(newAST, '<string>', 'exec') 

Ale kompilacji będzie akceptować tylko AST z krytym ast.Module jako root. Czy istnieje sposób, aby skompilować tylko ast.FunctionDef, lub pobrać obiekt kodu funkcji ze skompilowanego (i poza tym pusty) kodu modułu?

Wszelkie wskazówki dotyczące informacji obejmujących takie rzeczy byłyby mile widziane. Przykłady AST, które widziałem, dotyczą prostych wyrażeń.


Zdałem sobie sprawę, że muszę po prostu uruchomić moduł w przestrzeni nazw, to będę miał dostęp do normalnej struktury. więc wzór jest:

src = inspect.getsource(myClass.myMethod) 
astFromSrc = ast.parse(unindent(src))   # need to remove extra indent from method 
transform(astFromSrc.body)     # transform the AST as you need 
ast.fix_missing_locations(astFromSrc)   # fix up line numbers etc 
compiled = compile(astFromSrc, '<string>', 'exec') # compile the module AST 

####### From here is the part I was missing 
myScope = {}         # make an empty namespace 
exec compiled in myScope # now myScope contains a proper compiled function 

# Now replace the original with the modified version 
myClass.myMethod.__func__.__code__ = myScope['myMethod'].__code__ 

Ale teraz mam inne pytanie: Jak rowek do normalnego procesu kompilacji Pythona tak, że modyfikacje są wykonywane tylko raz, a następnie ładowane z pliku .pyc?

+2

Odkąd znalazłeś odpowiedź na swoje pytanie, opublikuj ją jako odpowiedź i zaakceptuj. – cpburnz

Odpowiedz

1

Nie powinieneś zadawać nowych pytań we własnej odpowiedzi, ale stwórz osobne pytanie na ten temat.

Pamiętaj, że twoje pierwsze i drugie pytanie również są sprzeczne. Najpierw chcesz robić rzeczy w środowisku wykonawczym, a później chcesz je zapisać do pliku, więc nie musisz tego robić w kółko. Podaj swój wynik końcowy, abyśmy dokładnie wiedzieli, czego chcesz.

Wygląda na to może równie dobrze utworzyć nowy plik .py po zmodyfikowaniu ast pliku, że analizowany jak wyjaśniono w Parse a .py file, read the AST, modify it, then write back the modified source code

będzie wtedy uzyskać plik pyc przez zebranie nowo utworzonego PY plik.