我想知道如何检查两个函数是否相同。例如,(lambda x: x) == (lambda y: y)
可以评估为True。据我所知,Python 会检查函数在内存中的位置是否相同,但不会检查它们是否具有相同的操作。我知道这似乎是不切实际的。
另一个解决方案是运行某些方法来查看函数包含什么或者它如何工作。因此可以使用 (lambda x: x).what()
这样的方法,返回方法的工作方式,可能是字典或其他形式。
我希望得到答案,但我怀疑这是不可能的。
您可以测试的唯一事项是代码对象的相等性:
>>> x = lambda x: x
>>> y = lambda y: y
>>> x.__code__.co_code
'|\x00\x00S'
>>> x.__code__.co_code == y.__code__.co_code
True
这两个函数的字节码是相同的。你可能需要验证代码对象的更多方面(如常量和闭包),但是相等的字节码应该等于相同的执行路径。
当然,有办法创建返回相同输入值的函数,但字节码不同; 总有更多的方法去做。
__globals__
也是一个例子。我认为我们不需要详尽的列表。 - abarnertco_consts
元组可能会有变化。 - Martijn Pieters1.26
版本中刚刚发生的那样。 - undefined如果你想知道两个函数是否对所有输入始终执行相同的操作,你将不得不在所有输入上同时运行它们(这将需要无限时间),并拦截所有可能的副作用(这实际上是不可能的)。
当然,你可以想出一些启发式方法,向它们抛出一组不同的值,如果函数不同,则非常可能生成不同的输出,适用于你的应用领域。但显然,这没有通用解决方案,否则所有单元测试都将自动生成,从而为我们节省大量工作,对吧?
相反,您可能只是想知道两个函数是否具有完全相同的实现。对此,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 的答案之外,真的没有什么可以自动化的东西)。
f==g
对我有效。 - lucidbrot