如果我声明两个函数 a
和 b
:
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/