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?
Odkąd znalazłeś odpowiedź na swoje pytanie, opublikuj ją jako odpowiedź i zaakceptuj. – cpburnz