2017-06-19 48 views
0

我想「在裏面」看看lambda表達式而不對其進行評估。 給出的表達式,如這裏的一個,對Lambda表達式的反省

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

我想以訪問所述lambda外部訪問的元素。 (即返回與引用列表,以something.xsomething.y

然而,正如我的表情可以有副作用,(lambda self: self.set_value(15))我想這樣做,而不實際調用的表達。這要求空隙覆蓋__getattr__的可能性簡短的例子,被傳遞到lambda對象

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 

我看着解析身體我自己,但我會訪問源代碼,並做一些字符串魔法清理源代碼-li (通過inspect收集)。

+5

我真的不明白你想做什麼。你能舉一個具體的例子來解釋它嗎? –

+0

您是否正在尋找'x'和'y'是從稱爲'something'的對象訪問的,而不需要將代碼添加到lambda函數中?如果是這樣,你可以嘗試覆蓋'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的參數不一致,儘管lambda函數實際上不應該那麼複雜,但這是可能的。哎呀,如果你的'lamda'可能會有副作用,任何事情都會發生:顫抖:: –

2

這與lambda表達式沒有任何關係。但是,如果你想看看都訪問了什麼屬性,你總是可以定義一個__getattribute__方法,顯示它的參數自定義類:

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

如果你現在傳遞到您的lambda表達式:

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

編輯它可能不是在所有情況下工作,但檢查拉姆達的__code__屬性的屬性顯示co_names屬性,它恰好包含('x', 'y')。不知道這對你是否足夠。

+0

我想過做這樣的事情。然而,問題是lambda可能有副作用(例如'something.x.setValue(15)'),所以非侵入性的方式(即不實際執行它)將是更可取的。 – stklik

+0

@ S.K。如何在不調用lambda的情況下知道'something'的身份?你真的需要澄清你的問題,確切地說你在找什麼。 –

+0

@ juanpa.arrivillaga基本上@丹尼爾 - 羅斯曼的答案將是解決方案的一半。我可以存儲/更新/獲取被訪問的'something'元素的列表。但是,爲此我需要調用'lambda',它將執行代碼。但是這在很多情況下會改變系統的狀態。這是否解釋我的問題? 我正在考慮使用一些解析方法,但我的Python知識不夠好。 – stklik