0

次のようなコードがあります。

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 はコードのインライン化を許可していないと思います。生成されたコード オブジェクトが呼び出し元関数の名前空間で実行されるように設定するにはどうすればよいですか?f1myscopemylib.codegen

4

1 に答える 1

0

には、特定の関数のfn.func_globalsグローバル名前空間が含まれています。変換および再コンパイルされたコード オブジェクトを実行できるようにするために必要です。

myscope = {}
myscope.update(fn.func_globals)

fn.func_globals直接使用しないでください。その名前空間のアイテムを上書きしたくないでしょう。

于 2012-12-13T07:16:06.683 に答える