检查两个Python函数是否相等
我想知道如何检查两个功能是否相同。一个示例将(lambda x: x) == (lambda y:
y)
评估为true。据我所知,Python将检查函数是否在内存中占据相同的位置,而不是它们是否具有相同的操作。我知道拥有该功能似乎不切实际。
另一个解决方案是我可以在函数上运行以查看其包含的内容或工作方式的某些方法。因此,其中一种(lambda x:
x).what()
将返回该方法的工作方式,可能是在字典中还是在某种形式中。
我希望得到一个答案,但我怀疑这是可能的。
-
如果您真的想知道两个函数是否总是对所有输入执行相同的操作,则必须在所有输入上同时运行它们(这将花费无限的时间),并且还必须拦截所有可能的副作用(实际上是不可能的)。
您当然可以想到一些启发式方法,向它们抛出一组不同的值,如果您使用的功能不同,则对于您的应用程序领域,它们很可能会产生不同的输出。但是显然没有通用的解决方案-
否则,所有单元测试都将自动生成,从而为我们节省了很多工作,对吗?
相反,您可能只想知道两个函数是否具有完全相同的实现。为此,Martijn
Pieters的答案是显而易见的起点,甚至可能是终点(取决于您是否关心闭包,全局变量等)。
但是您要的是与这两个都不相同的东西。您显然想手动查看代码以查看“它是如何工作的”:
另一个解决方案是我可以在函数上运行以查看其包含的内容或工作方式的某些方法。因此,一种(lambda
x:x).what()可以返回方法的工作方式,可能是在字典中还是在其他地方。该功能已经存在:
dis.dis
。在函数上运行它时,它会告诉您该函数的工作方式。不是在字典中(什么是字典?),而是在Python解释器的字节代码序列中(这是一个相对简单的堆栈机,上面添加了一些更高层次的内容,大部分在dis
文档中进行了描述)。或者,甚至更简单地,您可以使用获取源
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\n' >>> inspect.getsource(f2) 'f2 = lambda y: y\n' >>> inspect.getsource(f3) 'def f3(z):\n return z\n'
在第一种情况下,您需要了解足够的知识,
dis
以了解(x)
等等不是字节码的一部分,而是函数的本地名称列表的一部分。(在inspect
文档中以及在dis
文档中对此进行了解释。)在第二篇中,您需要对Python有足够的了解,以认识到def
和lambda
定义了完全相同的功能。因此,无论哪种方式,都无法
实现 这一目的的 自动化 (或者,实际上,Martijn不能解决的任何事情)。