检查两个 Python 函数是否相等 [英] Check if two Python functions are equal

查看:55
本文介绍了检查两个 Python 函数是否相等的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道如何检查两个函数是否相同.一个例子是 (lambda x: x) == (lambda y: y) 评估为真.据我所知,Python 会检查函数是否在内存中占据相同的位置,但不会检查它们是否具有相同的操作.我知道拥有该功能似乎不切实际.

另一种解决方案是一些方法,我可以在函数上运行以查看它包含的内容或它是如何工作的.所以一种 (lambda x: x).what() 将返回方法的工作方式,可能在字典或其他东西中.

我很想得到一个答案,但我怀疑这是可能的.

解决方案

如果你真的想知道两个函数是否总是对所有输入做同样的事情,你将不得不在所有输入上运行它们(这将需要无限时间),并拦截所有可能的副作用(这实际上是不可能的).

您当然可以想出一些启发式方法,向它们抛出一组不同的值,对于您的应用程序领域,如果函数不同,很可能会生成不同的输出.但显然没有通用的解决方案——否则,所有单元测试都会自动生成,为我们节省大量工作,对吧?

<小时>

相反,您可能只想知道两个函数是否具有完全相同的实现.为此,Martijn Pieters 的回答是显而易见的起点,甚至可能是终点(取决于您是否关心闭包、全局变量等).

<小时>

但是你所要求的与这两者都不一样;您显然想手动查看代码以了解它是如何工作的":

<块引用>

另一种解决方案是一些方法,我可以在函数上运行以查看它包含的内容或它是如何工作的.所以一种 (lambda x: x).what() 将返回方法的工作方式,可能在字典或其他东西中.

该函数已经存在:dis.dis.当你在一个函数上运行它时,它会告诉你这个函数是如何工作的.不是在字典(什么的字典?)中,而是在 Python 解释器的字节码行序列中(这是一个相对简单的堆栈机器,在顶部添加了一些更高级别的东西,主要在 中描述)dis 文档).

或者,更简单地说,您可以使用 inspect.getsource.

以下是您的示例中两者的外观:

<预><代码>>>>f1 = λ x: x>>>f2 = λ y: y>>>定义 f3(z):...返回z>>>dis.dis(f1)1 0 LOAD_FAST 0 (x)3 RETURN_VALUE>>>dis.dis(f2)1 0 LOAD_FAST 0 (y)3 RETURN_VALUE>>>dis.dis(f3)1 0 LOAD_FAST 0 (z)3 RETURN_VALUE>>>检查.getsource(f1)'f1 = lambda x: x '>>>检查.getsource(f2)'f2 = lambda y: y '>>>检查.getsource(f3)'def f3(z): 返回 z '

在第一种情况下,你需要对dis有足够的了解,才能意识到(x)等不是字节码的一部分,而是一部分函数的本地名称列表.(这在 inspect 文档和 dis 文档中的解释一样多.)第二,您需要对 Python 有足够的了解才能意识到 deflambda 定义了完全相同的函数.因此,无论哪种方式,都无法自动化此操作(或者,实际上,任何超出 Martijn 答案的方法).

I am wondering how I could check to see if two functions are the same. An example would be (lambda x: x) == (lambda y: y) evaluating to true. As far as I know, Python will check to see if the functions occupy the same location in memory, but not whether they have the same operation. I know it seems impractical to have that functionality.

Another solution would be some method I can run on a function to see what it contains or how it works. So a kind of (lambda x: x).what() that would return how the method works, maybe in a dictionary or something.

I would love an answer, but I doubt it's possible.

解决方案

If you really want to know whether two functions always do the same thing for all inputs, you will have to run them both on all inputs (which will take infinite time), and also intercept all possible side effects (which is effectively impossible).

You could of course come up with some heuristics, throwing a set of different values at them that, for your application area, are very likely to generate different outputs if the functions are different. But there's obviously no general-purpose solution to that—otherwise, all unit tests would be generated automatically, saving us all a whole lot of work, right?


Conversely, you might just want to know whether two functions have the exact same implementation. For that, Martijn Pieters's answer is the obvious starting point, and possibly even the ending point (depending on whether you care about closures, globals, etc.).


But what you asked for is something different from either of these; you apparently want to look over the code manually to see "how it works":

Another solution would be some method I can run on a function to see what it contains or how it works. So a kind of (lambda x: x).what() that would return how the method works, maybe in a dictionary or something.

That function already exists: dis.dis. When you run it on a function, it tells you how that function works. Not in a dictionary (a dictionary of what?) but in a sequence of lines of bytecode for the Python interpreter (which is a relatively simple stack machine with some higher-level stuff added on top, mostly described right there in the dis docs).

Or, even more simply, you can get the source with inspect.getsource.

Here's what the two look like with your examples:

>>> f1 = lambda x: x
>>> f2 = lambda y: y
>>> def f3(z):
...     return z
>>> dis.dis(f1)
  1           0 LOAD_FAST                0 (x)
              3 RETURN_VALUE
>>> dis.dis(f2)
  1           0 LOAD_FAST                0 (y)
              3 RETURN_VALUE
>>> dis.dis(f3)
  1           0 LOAD_FAST                0 (z)
              3 RETURN_VALUE
>>> inspect.getsource(f1)
'f1 = lambda x: x
'
>>> inspect.getsource(f2)
'f2 = lambda y: y
'
>>> inspect.getsource(f3)
'def f3(z):
    return z
'

In the first case, you need to know enough about dis to realize that the (x), etc., are not part of the bytecode, but rather part of the function's list of local names. (This is explained as much in the inspect docs as in the dis docs.) In the second, you need to know enough about Python to realize that the def and the lambda are defining the exact same function. So, either way, there's no way to automate this (or, really, anything much beyond Martijn's answer).

这篇关于检查两个 Python 函数是否相等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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