2012-09-20 117 views
1

在Python中我可以创建一个类无类声明:合成功能

MyClass = type('X', (object,), dict(a=1)) 

有没有一种方法来创建无“高清”的功能? 那只要我有...

d={} # func from string 
exec'''\ 
def synthetics(s): 
    return s*s+1 
''' in d 

>>> d.keys() 
['__builtins__', 'synthetics'] 
>>> d['synthetics'] 
<function synthetics at 0x00D09E70> 
>>> foo = d['synthetics'] 
>>> foo(1) 
2 
+2

'lambda'函数? – eumiro

+0

@ eumiro - :)我期待更多的解决方法,但不错的选择。 – root

+3

但是在lambda表达式中,你不能有赋值语句或'print'语句等。 – Kevin

回答

5

技术上,是的,这是可能的。该类型的函数的是,像所有其他类型,该类型的实例构造函数:

FunctionType = type(lambda: 0) 
help(FunctionType) 

你可以从帮助看,你需要最少的代码和全局。前者是一个编译的字节码对象;后者是一本字典。

为了使代码的对象,你可以使用代码类型的构造函数:

CodeType = type((lambda: 0).func_code) 
help(CodeType) 

帮助说,这是“不为微弱的心脏”这是真的。您需要将字节码和其他一些东西传递给此构造函数。因此,获取代码对象的最简单方法是使用另一个函数,或使用compile()函数。但它技术上可以完全合成生成代码对象,如果你理解Python字节码就够了。 (我已经这样做了,非常有限的基础上,构建签名保留包装函数用于装饰用途。)

PS - FunctionTypeCodeType也可通过types模块可用。

1

有可能比下面更直接的方式,但这里没有def一个全面的功能。首先,使用一个简单的lambda表达式得到一个功能对象:

>>> func = lambda: None 

然后,compile一些源代码来获得一个代码对象并用它来替代lambda的代码:

>>> func.__code__ = compile("print('Hello, world!')", "<no file>", "exec") 
>>> func() 
Hello, world! 
+0

@ larsmans - +1 – root

+1

函数类型也是:'func = types.FunctionType(compile(...),globals( ))' –