2016-09-08 9 views
0

コードを評価または実行するために必要なすべてのシンボルの名前のリストを取得する必要があります。私はsymtableモジュールを使用しようとしましたが、それは適切にラムダと内部関数(def他のコードの中に)を処理しないようです。ラムダ式のグローバルシンボルを特定する

import symtable 
symtable.symtable("x+y", '<string>', 'exec').get_symbols() 

私はこれを取得:[<symbol 'y'>, <symbol 'x'>]私は期待して正確に何であるこの考えてみましょう。

が、ときに私は、この書き込み:

symtable.symtable("z=lambda x: x+y; z(10)", '<string>', 'exec').get_symbols() 

結果は次のとおりです。[<symbol 'z'>]と私についてx(気にしない、それはローカル変数である)もy(グローバルであると、これはどのような私である何の情報を持っていませんが必要)。

しかし、これをexec("z=lambda x: x+y; z(10)")と評価しようとすると、yという値がありません。式/コードに評価/実行できるようにする必要があるすべてのシンボルの名前を識別できる方法はありますか?

+1

にインポートされている名前を取った場合、実際に可能な改善があるああ、私はそれを得ます!私には恥ずかしい...私は 'z'の子供のシンボルテーブルを見ることができます!それはいつものように、私はSOに質問を掲示したばかりのちょうど1分を自分で発見します。 :) –

+0

これを回答として投稿することを検討してください(理想的には簡単な例があります)。これは、今後も同じ質問をしている人にとっては役に立つかもしれません。 – BrenBarn

答えて

0

私は子供のシンボルテーブルを調べる必要があります。再帰は選択のツールです:

import symtable 

def find_global_symbols(table): 
    symbols = set() 
    for t in table.get_children(): 
     symbols |= find_global_symbols(t) 
    symbols |= set(s.get_name() for s in table.get_symbols() if s.is_global()) 
    return symbols 

table = symtable.symtable("z=lambda x: x+y; z(10)", '<string>', 'exec') 
global_symbols = find_global_symbols(table) 

これは私に答えとしてyを与えます。これは私が必要とするものです。問題のコードを実行できるようにするには、yの値を指定する必要があることがわかりました。

UPDATE:私は考慮に入れ、各スコープ

def find_global_symbols(table, imports): 
    imports = imports | set(s.get_name() for s in table.get_symbols() if s.is_imported()) 
    symbols = set() 
    for s in table.get_symbols(): 
     if s.is_global() and s.get_name() not in imports: 
      symbols.add(s.get_name()) 
    for t in table.get_children(): 
     symbols |= find_global_symbols(t, imports) 
    return symbols 

table = symtable.symtable("z=lambda x: x+y; z(10)", '<string>', 'exec') 
global_symbols = find_global_symbols(table, set())