次のようなコードがあります。
def f1():
<some stuff here>
.
.
.
@mylib.codegen
def f2(args):
f1()
<some more stuff here>
mylib.py :
def codegen(fn):
src = inspect.getsource(fn)
original_ast = ast.parse(src)
new_ast = transform_ast(original_ast)
code_obj = compile(new_ast, '<auto-generated>', 'exec')
myscope = {}
exec code_obj in myscope
fn.generated_fn = myscope['name'] # Where name is the binding created by execing code_obj
要約すると、mylib.codegen
は f のコードを解析し、 の ast に基づいて別の関数の ast を作成し、f
生成された関数のコードを実行して呼び出し可能な関数を取得し、呼び出し可能な関数を のプロパティとして設定するデコレータですf
。つまりf2
、初めてインポートされたときに、f2
別の関数をそれ自体のプロパティとして動的に取得します。
生成された関数も呼び出す必要がありますが、f1
では見つかりません。どういうわけか Python がインライン化を許可していて、私が のインライン化されたコードを持っていた場合、すべてがうまくいったでしょうが、Python はコードのインライン化を許可していないと思います。生成されたコード オブジェクトが呼び出し元関数の名前空間で実行されるように設定するにはどうすればよいですか?f1
myscope
mylib.codegen