如何找出一个函数是否已经被`lambda`或`def`声明? [英] How to find out if a function has been declared by `lambda` or `def`?

查看:91
本文介绍了如何找出一个函数是否已经被`lambda`或`def`声明?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我声明两个函数ab:

If I declare two functions a and b:

def a(x):
    return x**2

b = lambda x: x**2

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

I can not use type to differentiate them, since they're both of the same type.

assert type(a) == type(b)

此外,types.LambdaType也无济于事:

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

一个人可以像这样使用__name__:

One could use __name__ like:

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

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

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

However, since __name__ could have been modified, is_lambda_function is not guaranteed to return the correct result:

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

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

Is there a way which produces a more reliable result than the __name__ attribute?

推荐答案

AFAIK,您无法在Python 3中可靠地使用.

AFAIK, you cannot reliably in Python 3.

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

Python 2 used to define a bunch of function types. For that reason, methods, lambdas and plain functions have each their own type.

Python 3只有一种类型为function.在使用deflambda声明常规函数的过程中确实存在不同的副作用:def将名称设置为该函数的名称(和限定名称)并可以设置文档字符串,而lambda设置该字符串名称(和限定名称)为<lambda>,并将文档字符串设置为无".但是由于可以更改...

Python 3 has only one type which is function. There are indeed different side effects where declaring a regular function with def and a lambda: def sets the name to the name (and qualified name) of the function and can set a docstring, while lambda sets the name (and qualified name) to be <lambda>, and sets the docstring to None. But as this can be changed...

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

If the functions are loaded from a regular Python source (and not typed in an interactive environment), the inspect module allows to access the original Python code:

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的函数进行腌制,前提是您为其指定了唯一的合格名称:

By the way, if the problem was serialization of function, a function declared as a lambda can successfully be pickled, provided you give it a unique qualified name:

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

这篇关于如何找出一个函数是否已经被`lambda`或`def`声明?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆