有什么办法可以判断一个函数对象是lambda还是def?

wim*_*wim 5 python lambda python-datamodel

请考虑以下两个功能:

def f1():
    return "potato"

f2 = lambda: "potato"
f2.__name__ = f2.__qualname__ = "f2"
Run Code Online (Sandbox Code Playgroud)

缺少对原始源代码的自省,是否有任何方法可以检测到f1是def和f2lambda?

>>> black_magic(f1)
"def"
>>> black_magic(f2)
"lambda"
Run Code Online (Sandbox Code Playgroud)

use*_*ica 15

您可以检查代码对象的名称。与函数名称不同,不能重新分配代码对象的名称。Lambda的代码对象的名称仍为'<lambda>'

>>> x = lambda: 5
>>> x.__name__ = 'foo'
>>> x.__name__
'foo'
>>> x.__code__.co_name
'<lambda>'
>>> x.__code__.co_name = 'foo'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: readonly attribute
Run Code Online (Sandbox Code Playgroud)

这是不可能的def语句来定义其代码对象的名称是一个函数'<lambda>'。这可能的创建后替换函数的代码对象,但这样做是罕见的,怪异的,以至于它可能不值得操作。同样,这将无法处理通过手动调用types.FunctionType或创建的函数或代码对象types.CodeType。我看不到任何好的方法来处理__code__重新分配或手动创建的函数和代码对象。

  • 可以说,关心通过lambda表达式还是通过def语句创建函数是稀有且奇怪的。 (4认同)
  • @alkasm 不,你没有。它是相同的 `function` 对象,但有一个新的主体。您没有替换全局命名空间、闭包、默认参数值等。 (2认同)