我希望能够像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