python - 如何确定函数是否已由 `lambda` 或 `def` 声明?

标签 python function lambda types function-declaration

如果我声明两个函数 ab:

def a(x):
    return x**2

b = lambda x: x**2

我不能使用 type 来区分它们,因为它们都是同一类型。

assert type(a) == type(b)

此外,types.LambdaType 也没有帮助:

>>> import types
>>> isinstance(a, types.LambdaType)
True
>>> isinstance(b, types.LambdaType)
True

可以像这样使用 __name__:

def is_lambda_function(function):
    return function.__name__ == "<lambda>"

>>> is_lambda_function(a)
False
>>> is_lambda_function(b)
True

但是,由于 __name__ 可能已被修改,因此不能保证 is_lambda_function 返回正确的结果:

>>> a.__name__ = '<lambda>'
>>> is_lambda_function(a)
True

有没有一种方法可以产生比 __name__ 属性更可靠的结果?

最佳答案

据我所知,您不能可靠地使用 Python 3。

Python 2 用于定义一堆函数类型。因此,方法、lambda 和普通函数都有自己的类型。

Python 3 只有一种类型,即 function .使用 def 声明常规函数确实有不同的副作用和一个 lambda : def将名称设置为函数的名称(和限定名称)并可以设置文档字符串,而 lambda将名称(和限定名称)设置为 <lambda> ,并将文档字符串设置为无。但是因为这可以改变...

如果函数是从常规 Python 源加载的(而不是在交互式环境中键入的),则 inspect模块允许访问原始 Python 代码:

import inspect

def f(x):
    return x**2

g = lambda x: x**2

def is_lambda_func(f):
    """Tests whether f was declared as a lambda.

Returns: True for a lambda, False for a function or method declared with def
Raises:
    TypeError if f in not a function
    OSError('could not get source code') if f was not declared in a Python module
                                         but (for example) in an interactive session
"""
    if not inspect.isfunction(f):
        raise TypeError('not a function')
    src = inspect.getsource(f)
    return not src.startswith('def') and not src.startswith('@') # provision for decorated funcs

g.__name__ = 'g'
g.__qualname__ = 'g'

print(f, is_lambda_func(f))
print(g, is_lambda_func(g))

这将打印:

<function f at 0x00000253957B7840> False
<function g at 0x00000253957B78C8> True

顺便说一下,如果问题是函数的序列化,声明为 lambda 的函数可以成功 pickle,只要你给它一个唯一的合格名称:

>>> g = lambda x: 3*x
>>> g.__qualname__ = "g"
>>> pickle.dumps(g)
b'\x80\x03c__main__\ng\nq\x00.'

关于python - 如何确定函数是否已由 `lambda` 或 `def` 声明?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54094263/

相关文章:

c++ - VS2008 SP1 中的 Lambda 表达式支持

reflection - Kotlin:使用(输出)反射比较不同目标对象的属性值

python - h2o python 平衡类

python - 将数千个文件(按名称过滤)复制到指定文件夹

python替代解决方案scipy空间距离,当前解决方案返回MemoryError

javascript - 严格验证 Javascript xhtml 1.0 中的表单数据,不考虑此实例的服务器端脚本

android - onClick() 的函数在下次点击时返回数据,但不会在同一次点击时返回

c# - 在运行时创建 lambda 表达式

python - 如何将过滤后的excel表格导入python?

c - 搜索和编辑功能没有复制粘贴?