如何找出一个函数是否已被`lambda`或`def`声明?
发布时间:2020-12-20 11:09:08 所属栏目:Python 来源:网络整理
导读:如果我声明两个函数a和b: def a(x): return x**2b = lambda x: x**2 我不能使用类型来区分它们,因为它们都是相同的类型. assert type(a) == type(b) 另外,types.LambdaType没有帮助: import types isinstance(a,types.LambdaType)True isinstance(b,types.
如果我声明两个函数a和b:
def a(x): return x**2 b = lambda x: x**2 我不能使用类型来区分它们,因为它们都是相同的类型. 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__属性更可靠的结果? 解决方法
AFAIK,你无法在Python 3中可靠地使用.
Python 2用于定义一堆函数类型.因此,方法,lambda和普通函数各有各自的类型. Python 3只有一种类型是函数.确实使用def和lambda声明常规函数确实存在不同的副作用:def将名称设置为函数的名称(和限定名称),并且可以设置docstring,而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)) 这将打印: <function f at 0x00000253957B7840> False <function g at 0x00000253957B78C8> True 顺便说一下,如果问题是函数的序列化,声明为lambda的函数可以成功地被pickle,只要你给它一个唯一的限定名: >>> g = lambda x: 3*x >>> g.__qualname__ = "g" >>> pickle.dumps(g) b'x80x03c__main__ngnqx00.' (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |