2011-08-15 6 views
9

私はPythonでASTを試しています。実行時にASTを変換することによってメソッドを変更したい。Python ASTをメソッドにコンパイル

inspect.getsource()と を使用して、事前コンパイルされたメソッドのソースを取得できます。必要に応じて、AST訪問者を使用してASTを変更できます。

これはおそらく非常にナイーブであるが、私はASTをコンパイルしに似て何かをできるようにしたいと思います:

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

しかし、コンパイルは唯一のルートとしてast.ModuleとASTを受け入れます。 ast.FunctionDefだけをコンパイルする方法、またはコンパイルされた(さもなければ空の)モジュールコードから関数コードオブジェクトを取り出す方法はありますか?

この種の情報をカバーする情報への参考になります。シンプルな表現を扱ったASTの例です。


私はネームスペースでモジュールを実行する必要があることに気がついたので、通常の構造にアクセスできます。 ので、パターンは次のとおりです。

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__ 

しかし、今、私は別の質問があります。 変更が一度だけ行われ、その後に.pycファイルからロードされるように、通常のPythonのビルドプロセスにこれをスロットにどのように?

+2

あなたの質問に対する答えが見つかったので、答えとして投稿し、それを受け入れます。 – cpburnz

答えて

1

あなた自身の答えで新しい質問をするのではなく、別の質問を作成すべきです。

あなたの最初と2番目の質問も矛盾していることに注意してください。最初は実行時に処理を行いたいが、後でそれらをファイルに書きたいので、何度も繰り返し実行する必要はありません。あなたのエンドゴールはあなたが望むものを明確に知っていることを明記してください。

それはあなただけで、同様Parse a .py file, read the AST, modify it, then write back the modified source code

に説明するように、あなたはその後、新しく作成されたPYをコンパイルすることにより、あなたのPYCファイルを取得する解析されたファイルのASTを変更した後、新規の.pyファイルを作成することがありますように聞こえますファイル。

関連する問題