2011-04-26 67 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

相关问题