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

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

问题描述

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

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



我很想回答,但我怀疑这是可能的。 解决方案

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



当然,您可以想出一些启发式方法,并在其中引入一组不同的值,以便在您的应用程序领域,如果函数不同,很可能会生成不同的输出。但是显然没有通用的解决方案 - 否则,所有的单元测试都会自动生成,从而为我们节省大量工作,对吗?




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






但是你所要求的与这两者中的任何一个都有所不同;你显然想手动查看代码,看看它是如何工作的:


另一个解决方案是我可以运行的一种方法函数来查看它包含的内容或它的工作原理。因此,一种(lambda x:x).what()将返回该方法的工作方式,可能在字典或其他东西中。


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

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



下面是你的例子中的两个:

 >>> 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\''

在第一种情况下,您需要充分了解 dis 才能认识到(x)等等,不是字节码的一部分,而是函数本地名称列表的一部分。 (这在 inspect docs中有很多解释,如 dis 文档中所述)。第二,您需要对Python的了解足以认识到 def lambda 定义了完全相同的函数。所以,无论哪种方式,都无法自动化这个(或者,实际上,超出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\n'
>>> inspect.getsource(f2)
'f2 = lambda y: y\n'
>>> inspect.getsource(f3)
'def f3(z):\n    return z\n'

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天全站免登陆