我希望能夠像C#那樣從lambda函數中獲取表達式並將其解析爲其他內容?在C#
示例:在python中是否有一個等價的Linq.Expressions.Expression?
void Foo<T>(Expression<Func<T, bool>> expression
{
// ...
}
Foo<Baz>(someObj => someObj.HasBar);
拉姆達操作者將traslated到可能被檢查的表達式。
python中的equilivent是什麼?
我希望能夠像C#那樣從lambda函數中獲取表達式並將其解析爲其他內容?在C#
示例:在python中是否有一個等價的Linq.Expressions.Expression?
void Foo<T>(Expression<Func<T, bool>> expression
{
// ...
}
Foo<Baz>(someObj => someObj.HasBar);
拉姆達操作者將traslated到可能被檢查的表達式。
python中的equilivent是什麼?
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'
>>>
這就像是用'gcc -S'回答C AST的問題... – delnan 2011-04-26 06:20:29
有沒有更好的方法來做到這一點? – 2011-04-26 06:52:09
@delnan:不完全。 co_code字段是實際的字節碼,您可以使用相對簡單的堆棧機重新構建AST。這是相當神祕的東西,但它不應該需要超過幾十行代碼。 – 2011-04-26 06:53:43
出於好奇:你爲什麼需要這個?儘管我喜歡和包括AST在內的與編譯器相關的東西擺弄,但我並不知道這在一些極端的元編程之外很有用。 – delnan 2011-04-26 06:22:32
@delnan:因爲lambda表達式可以被翻譯爲一個SQL語句。我想知道是否可以改進Django ORM的查詢API。 – 2011-04-26 06:51:50
@delnan:我假設出於同樣的原因,C#中有Expression <> - 將代碼轉換爲SQL以在數據庫後端運行它。將ECMA腳本翻譯爲使Web工具包在客戶端透明地運行,我也同樣感興趣。 – 2011-04-26 06:52:38