2017-06-19 6 views
0

ラムダ式を評価せずに "内部"を見たいと思っています。 はラムダ式のイントロスペクション

(lambda something: something.x > something.y) 

私はlambda外部からアクセスされている要素にアクセスしたい、などここでは1として式を考えます。 (Ieはsomething.xsomething.yへの参照を持つリストを返す。

をしかし、私の式が副作用を持つことができるよう、(lambda self: self.set_value(15)を)私は実際に式を呼び出すことなく、これをやりたい。この要件はで__getattr__を上書きする可能性を無効に。

l = (lambda something: something.x > something.y) 
something = Something() 
elements = l.get_accessed_elements(something) 
# elements is a list where 
# elements[0] points to something.x, and 
# elements[1] points to something.y 

私は身体を自分で解析するに見えたが、私は、ソースコードにアクセスして、ソースをきれいにするために、いくつかの文字列の魔法を行う必要があります:lambdaに渡されている

ショート例を対象-li nes(inspectを介して収集)。

+5

をあなたがしようとしていることを理解していない。あなたはそれを説明する具体的な例を挙げることができますか? –

+0

ラムダ関数のコードを持たずに 'x'と' y'が 'something'と呼ばれるオブジェクトからアクセスされていることを知りたいですか?もしそうなら、 'something'がインスタンスであるクラスの定義で' __getattr__'メソッドをオーバーライドすることができます – inspectorG4dget

+0

'lambda something:print(something)またはsomething.x> something.y' –

答えて

1

私は、これは視覚的な検査が必要になると思い、けれどもあなたは、分解されたバイトコードにアクセスすることができます:

>>> import dis 
>>> dis.dis((lambda something: something.x > something.y)) 
    1   0 LOAD_FAST    0 (something) 
       3 LOAD_ATTR    0 (x) 
       6 LOAD_FAST    0 (something) 
       9 LOAD_ATTR    1 (y) 
      12 COMPARE_OP    4 (>) 
      15 RETURN_VALUE 
>>> 

あなたは、同様に、プログラムの効果に何かこれを行うことができます:私は本当に

>>> bc = dis.Bytecode(lambda something: something.x > something.y) 
>>> for instr in bc: 
...  if instr.opname == "LOAD_ATTR": 
...   print(instr.argval) 
... 
x 
y 
>>> 
+0

@ S.K。 'LOAD_ATTR'から得られる値はラムダに渡される引数に対応しないかもしれませんが、' lambda'関数は本当にその複雑ではないはずですが、それは可能です。あなたの 'lamda'が潜在的な副作用を持つ可能性があるなら何でも行く:: shudders :: –

2

これは実際にラムダ式とは関係ありません。あなたがアクセスしているかの属性を参照しようとしている場合しかし、あなたは常にその引数を出力します__getattribute__方法でカスタムクラスを定義することができます

class Something(object): 
    def __getattribute__(self, name): 
     print("{} was accessed".format(name)) 

今、あなたのラムダ式にそれを渡す場合:

>>> l = lambda something: something.x > something.y 
>>> s = Something() 
>>> l(s) 
x was accessed 
y was accessed 

編集コメント後にそれはすべてのケースで動作しますが、ラムダの__code__属性の属性を調べると('x', 'y')を含むように起こるco_names属性を示していない可能性があります。それがあなたのために十分であるかどうかは分かりません。

+0

私はこのようなことをすると思った。しかし、ラムダには副作用(例えば 'something.x.setValue(15)')があるかもしれないので、非侵入的な方法(つまり実際には実行しない)が望ましいでしょう。 – stklik

+0

@ S.K。ラムダを使わずに「何か」のアイデンティティをどうやって知ることができますか?あなたは本当にあなたが探しているものを正確にあなたの質問を明確にする必要があります。 –

+0

@ juanpa.arrivillaga @ Daniel-Rosemanの答えは、半分の解です。私はアクセスした 'something'の要素のリストを格納/更新/取得することができました。しかし、そのためには、コードを実行する 'lambda'を呼び出す必要があります。しかし、これは多くの場合、システムの状態を変えることができます。これは私の問題を説明していますか? 私はいくつかの構文解析手法を使用することを考えていましたが、私のPython知識は十分ではありません。 – stklik