fin*_*oot 4 python lambda types function function-declaration
如果我声明两个函数,a
并且b
:
def a(x):
return x**2
b = lambda x: x**2
Run Code Online (Sandbox Code Playgroud)
我无法type
区分它们,因为它们都属于同一类型.
assert type(a) == type(b)
Run Code Online (Sandbox Code Playgroud)
另外,types.LambdaType
没有帮助:
>>> import types
>>> isinstance(a, types.LambdaType)
True
>>> isinstance(b, types.LambdaType)
True
Run Code Online (Sandbox Code Playgroud)
人们可以使用__name__
如下:
def is_lambda_function(function):
return function.__name__ == "<lambda>"
>>> is_lambda_function(a)
False
>>> is_lambda_function(b)
True
Run Code Online (Sandbox Code Playgroud)
但是,由于__name__
可能已被修改,is_lambda_function
因此无法保证返回正确的结果:
>>> a.__name__ = '<lambda>'
>>> is_lambda_function(a)
True
Run Code Online (Sandbox Code Playgroud)
有没有一种方法可以产生比__name__
属性更可靠的结果?
AFAIK,你无法在Python 3中可靠地使用.
Python 2用于定义一堆函数类型.因此,方法,lambda和普通函数各有各自的类型.
Python 3只有一种类型function
.在使用def
和声明常规函数时确实存在不同的副作用lambda
:def
将名称设置为函数的名称(和限定名称)并设置文档字符串,同时lambda
将名称(和限定名称)设置为<lambda>
,并设置docstring为None.但是这可以改变......
如果函数是从常规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))
Run Code Online (Sandbox Code Playgroud)
这将打印:
<function f at 0x00000253957B7840> False
<function g at 0x00000253957B78C8> True
Run Code Online (Sandbox Code Playgroud)
顺便说一下,如果问题是函数的序列化,声明为lambda的函数可以成功地被pickle,只要你给它一个唯一的限定名:
>>> g = lambda x: 3*x
>>> g.__qualname__ = "g"
>>> pickle.dumps(g)
b'\x80\x03c__main__\ng\nq\x00.'
Run Code Online (Sandbox Code Playgroud)