AFAIK, вы не можете надежно работать в Python 3.
Python 2 используется для определения группы типов функций. По этой причине методы, лямбды и простые функции имеют каждый свой тип.
Python 3 имеет только один тип, function
. Действительно, существуют различные побочные эффекты, когда объявление обычной функции с помощью def
и lambda
: def
устанавливает имя для имени (и квалифицированного имени) функции и может устанавливать строку документации, тогда как lambda
устанавливает name (и полное имя), равное <lambda>
, и задает строку документации 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))
Будет напечатано:
<function f at 0x00000253957B7840> False
<function g at 0x00000253957B78C8> True
Кстати, если проблема заключалась в сериализации функции, функция, объявленная как лямбда, может быть успешно выбрана, если вы дадите ей уникальное квалифицированное имя:
>>> g = lambda x: 3*x
>>> g.__qualname__ = "g"
>>> pickle.dumps(g)
b'\x80\x03c__main__\ng\nq\x00.'