2011-04-26 30 views
1

我希望能夠像C#那樣從lambda函數中獲取表達式並將其解析爲其他內容?在C#
示例:在python中是否有一個等價的Linq.Expressions.Expression?

void Foo<T>(Expression<Func<T, bool>> expression 
{ 
// ... 
} 

Foo<Baz>(someObj => someObj.HasBar); 

拉姆達操作者將traslated到可能被檢查的表達式。
python中的equilivent是什麼?

+0

出於好奇:你爲什麼需要這個?儘管我喜歡和包括AST在內的與編譯器相關的東西擺弄,但我並不知道這在一些極端的元編程之外很有用。 – delnan 2011-04-26 06:22:32

+0

@delnan:因爲lambda表達式可以被翻譯爲一個SQL語句。我想知道是否可以改進Django ORM的查詢API。 – 2011-04-26 06:51:50

+0

@delnan:我假設出於同樣的原因,C#中有Expression <> - 將代碼轉換爲SQL以在數據庫後端運行它。將ECMA腳本翻譯爲使Web工具包在客戶端透明地運行,我也同樣感興趣。 – 2011-04-26 06:52:38

回答

1

Python提供了完整的編譯形式的代碼。

>>> f = lambda(x): 2*x 
>>> f.func_code.co_code 
'd\x00\x00|\x00\x00\x14S' 
>>> 

原則上,您可以對此進行逆向工程以找出表達式,儘管這樣做絕非易事。 dis模塊可能會給你一點啓動:

>>> import dis 
>>> dis.dis(f) 
    1   0 LOAD_CONST    0 (2) 
       3 LOAD_FAST    0 (x) 
       6 BINARY_MULTIPLY  
       7 RETURN_VALUE   
>>> dis.opname[ord(f.func_code.co_code[-2])] 
'BINARY_MULTIPLY' 
>>> dis.opname[ord(f.func_code.co_code[-1])] 
'RETURN_VALUE' 
>>> 
+1

這就像是用'gcc -S'回答C AST的問題... – delnan 2011-04-26 06:20:29

+0

有沒有更好的方法來做到這一點? – 2011-04-26 06:52:09

+0

@delnan:不完全。 co_code字段是實際的字節碼,您可以使用相對簡單的堆棧機重新構建AST。這是相當神祕的東西,但它不應該需要超過幾十行代碼。 – 2011-04-26 06:53:43

相關問題