gpt4 book ai didi

python - 如何检查函数是否在 Python 中是纯函数?

转载 作者:太空狗 更新时间:2023-10-29 18:05:21 25 4
gpt4 key购买 nike

A pure function是一个类似于数学函数的函数,其中没有与“真实世界”的交互,也没有副作用。从更实际的角度来看,这意味着纯函数可以:

  • 打印或以其他方式显示消息
  • 随机
  • 取决于系统时间
  • 更改全局变量
  • 及其他

所有这些限制使得纯函数比非纯函数更容易推理。大多数功能应该是纯的,这样程序才能有更少的错误。

在像 Haskell 这样具有庞大类型系统的语言中,读者可以从一开始就知道函数是否是纯函数,从而使后续阅读更加容易。

在 Python 中,此信息可以通过放在函数顶部的 @pure 装饰器来模拟。我还希望那个装饰器真正做一些验证工作。我的问题在于这样一个装饰器的实现。

现在我只是简单地查看函数的源代码,寻找诸如 globalrandomprint 之类的流行语,如果找到一个就会提示

import inspect

def pure(function):
source = inspect.getsource(function)
for non_pure_indicator in ('random', 'time', 'input', 'print', 'global'):
if non_pure_indicator in source:
raise ValueError("The function {} is not pure as it uses `{}`".format(
function.__name__, non_pure_indicator))
return function

然而,这感觉像是一个奇怪的 hack,它可能会或可能不会取决于你的运气,你能帮我写一个更好的装饰器吗?

最佳答案

我有点明白你来自哪里,但我认为这行不通。让我们举一个简单的例子:

def add(a,b):
return a + b

所以这对你来说可能看起来是“纯粹的”。但是在 Python 中,这里的 + 是一个可以做任何事情的任意函数,仅取决于调用它时有效的绑定(bind)。所以 a + b 可以有任意的副作用。

但情况比这更糟。即使这只是在执行标准整数 +,也会发生更多“不纯”的事情。

+ 正在创建一个新对象。现在,如果您确定只有调用者拥有对该新对象的引用,那么您可以将其视为一个纯函数。但是您不能确定,在该对象的创建过程中,没有泄漏对它的引用。

例如:

class RegisteredNumber(int):

numbers = []

def __new__(cls,*args,**kwargs):
self = int.__new__(cls,*args,**kwargs)
self.numbers.append(self)
return self

def __add__(self,other):
return RegisteredNumber(super().__add__(other))

c = RegisteredNumber(1) + 2

print(RegisteredNumber.numbers)

这将表明假定的纯添加函数实际上已经更改了 RegisteredNumber 类的状态。这不是一个愚蠢的人为设计的例子:在我的生产代码库中,我们有类跟踪每个创建的实例,例如,允许通过 key 访问。

纯度的概念在 Python 中没有多大意义。

关于python - 如何检查函数是否在 Python 中是纯函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31568441/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com