8

これは簡単なように思えますが、どこにも答えが見つかりません。また、自分で答えを導き出すこともできません。引用符で囲まれていないpython関数/ラムダをASTに変換するにはどうすればよいですか?

これが私ができるようにしたいことです。

import ast
class Walker(ast.NodeVisitor):
    pass
    # ...

# note, this doesnt work as ast.parse wants a string
tree = ast.parse(lambda x,y: x+y)

Walker().visit(tree)
4

5 に答える 5

10

一般的には、できません。たとえば、2 + 2は式ですが、それを任意の関数またはメソッドに渡す場合、渡される引数は単なる数値4であり、計算元の式を復元する方法はありません。関数のソース コードは復元できる場合がありますが (a の場合lambdaは除く)、「引用符で囲まれていない Python 式」が評価されるため、取得されるのは式の値であるオブジェクトだけです。

どのような問題を解決しようとしていますか? 他の実行可能なアプローチがあるかもしれません。

編集:明確にするためにOPにtx。または他のいくつかのコーナーケースでそれを行う方法はありませんlambdaが、私が言及したように、関数のソースコードを復元できる場合があります...:

import ast
import inspect

def f():
  return 23

tree = ast.parse(inspect.getsource(f))

print ast.dump(tree)

inspect.getsource渡しIOErrorたオブジェクトのソースコードを取得できない場合に発生します。解析と getsource 呼び出しを、文字列を受け入れる (そして解析するだけ) または関数 (そして getsource を試行し、そのIOError場合により良いエラーが発生する可能性がある) を補助関数にラップすることをお勧めします。

于 2009-09-23T22:03:27.373 に答える
6

関数/ラムダにしかアクセスできない場合は、コンパイルされた python バイトコードしかありません。コンパイル プロセスで情報が失われるため、バイトコードから正確な Python AST を再構築することはできません。ただし、バイトコードを分析して、そのための AST を作成できます。GeniuSQL には、そのようなアナライザーが 1 つあります。また、バイトコードを分析し、そこから SQLAlchemy 節要素を作成する小さな概念実証もあります。

分析に使用したプロセスは次のとおりです。

  1. コードを潜在的な引数を持つオペコードのリストに分割します。
  2. オペコードを調べてコード内の基本ブロックを見つけ、ジャンプごとに、ジャンプの後とジャンプターゲットの前に基本ブロック境界を作成します
  3. 基本ブロックから制御フロー グラフを作成します。
  4. 抽象解釈追跡スタックと SSA 形式の変数割り当てを使用して、すべての基本ブロックを確認します。
  5. 出力式を作成するには、計算された SSA 戻り値を取得するだけです。

概念実証それを使用したサンプル コードを貼り付けました。これはクリーンではなく、すぐにハッキングされたコードですが、必要に応じて自由にビルドできます。そこから何か役に立つものを作ることにした場合は、メモを残してください。

于 2009-09-24T08:52:11.153 に答える
5

メタライブラリを使用すると、内包表記やラムダなどのいくつかの例外を除いて、多くの場合、ソースを回復できます。

import meta, ast
source = '''
a = 1
b = 2
c = (a ** b)
'''

mod = ast.parse(source, '<nofile>', 'exec')
code = compile(mod, '<nofile>', 'exec')

mod2 = meta.decompile(code)
source2 = meta.dump_python_source(mod2)

assert source == source2
于 2012-08-30T19:23:35.463 に答える
2

コンパイルされたバイトコードからASTを生成することはできません。ソースコードが必要です。

于 2009-09-23T23:33:28.367 に答える
0

あなたのラムダ式は多くの情報を持つ関数ですが、ソースコードが関連付けられているとは思いません。あなたが欲しいものを手に入れることができるかどうかはわかりません。

于 2009-09-23T21:37:45.490 に答える