【问题标题】:Synthetic functions in pythonpython中的合成函数
【发布时间】:2012-09-20 13:04:47
【问题描述】:

在python中我可以创建一个没有class语句的类:

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

有没有办法创建一个没有'def'的函数? 就我所知……

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

【问题讨论】:

  • @eumiro -- :) 我期待更多的解决方法,但很好的选择。
  • 但在 lambdas 中,你不能有赋值或print 语句等。

标签: python function python-internals


【解决方案1】:

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

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

从帮助中可以看出,您至少需要代码和全局变量。前者是编译后的字节码对象;后者是字典。

要制作代码对象,可以使用代码类型的构造函数:

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

帮助说这“不适合胆小的人”,这是真的。你需要将字节码和一堆其他的东西传递给这个构造函数。因此,获取代码对象的最简单方法是从另一个函数,或使用compile() 函数。但是,如果您足够了解 Python 字节码, 在技术上完全可以生成代码对象。 (我做了这个,在非常有限的基础上,构建用于装饰器的签名保留包装函数。)

PS -- FunctionTypeCodeType 也可以通过 types 模块获得。

【讨论】:

    【解决方案2】:

    可能有比以下更直接的方法,但这里有一个没有def 的完整功能。首先,使用一个简单的lambda 表达式来获取一个函数对象:

    >>> func = lambda: None
    

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

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

    【讨论】:

    • 还有一个函数类型:func = types.FunctionType(compile( ... ), globals())
    猜你喜欢
    • 2016-12-22
    • 2018-01-28
    • 1970-01-01
    • 2016-07-21
    • 2019-08-17
    • 2013-05-20
    • 2023-03-07
    • 1970-01-01
    相关资源
    最近更新 更多