如何判断(或如何编写)一个没有副作用的python函数?

2024-09-30 03:25:23 发布

您现在位置:Python中文网/ 问答频道 /正文

答案等于side effects的定义。在

到目前为止,我还没有找到一个确切的答案。python医生说: Functional style discourages functions with side effects that modify internal state or make other changes that aren’t visible in the function’s return value.

什么是modify internal state和{}?在

将变量绑定到对象(只是绑定,而不是修改)是否意味着没有副作用?e、 g.a=1或{}或{}。在

这里有4个函数。它们都没有副作用吗?为什么?在

注意,假设参数n必须是int对象。在

def purefunc1(n):
    def getn(n):
        return [1,2,3,4,5][:n-1],[1,2,3,4,5][:n]
    def addn(fir,sec,thd):
        return fir+sec+thd
    return addn(getn(n)[0],['HEY'],getn(n)[1])

def purefunc2(n):
    def getn(n):
        #bind
        arr=[1,2,3,4,5]
        return arr[:n-1],arr[:n]
    def addn(fir=[],sec=[],thd=[]):
        return fir+sec+thd
    #bind
    arg1,arg3=getn(n)
    return addn(arg1,['HEY'],arg3)

def purefunc3(n):
    arr=[1,2,3,4,5]
    def getn(n):
        #closure 'arr'
        return arr[:n-1],arr[:n]
    def addn(fir=[],sec=[],thd=[]):
        return fir+sec+thd
    #bind
    arg1,arg3=getn(n)
    return addn(arg1,['HEY'],arg3)

def purefunc4(n):
    def arr():
        return [1,2,3,4,5]
    def getn(n):
        #closure
        return arr()[:n-1],arr()[:n]
    def addn(fir=[],sec=[],thd=[]):
        return fir+sec+thd
    #bind
    arg1,arg3=getn(n)
    return addn(arg1,['HEY'],arg3)

print (purefunc1(3))
print (purefunc2(3))
print (purefunc3(3))
print (purefunc4(3))

我猜:purefunc1是没有边的影响。但是我不知道下面的purefunc*。在

输出为:

^{pr2}$

如果你问为什么会有这样奇怪的函数,答案是这只是为了方便。实际函数很复杂。但是如果您感兴趣,您可以click here看看函数ieval是否没有副作用。在

提前谢谢大家。在


Tags: 函数答案returnbinddefsecarg3print
3条回答

Python函数只有在不修改全局变量、只调用没有副作用的函数和doesn't raise exceptions which are caught时才会有副作用。 引用维基百科:

In computer science, a function or expression is said to have a side effect if, in addition to returning a value, it also modifies some state or has an observable interaction with calling functions of the outside world.

基本上可以调用一个没有副作用的函数,调用后没有什么不同,即调用后一切都是一样的。在

在函数编程的上下文中,函数是一个确定性的东西,给定一个输入,输出一些东西。这就是纯函数的作用。他们只计算东西。他们不“做”事情。如果你的函数代码理论上可以被一个表(甚至是无限的表)切换,那么你就得到了一个没有副作用的函数。在

任何东西除了返回值之外,这都是一个副作用。术语“修改内部状态”和“进行其他不可见的更改”都是指这一点。正在修改内部状态或进行更改。。。can是指:

  1. 打印东西
  2. 修改超出范围的对象
  3. 保存一些东西

你可以把副作用理解为“改变外部世界”。在你的例子中,没有一个这样做。但是,如果你给n分配了一些东西,比如附加一些东西,或者在函数返回后在你的环境中持续存在的任何东西,那么这将是一个副作用。在

所有的功能都可以通过比较输入和输出进行测试。如果你有副作用(比如变异n),你的测试会变得更复杂,你需要分析你的功能所在的上下文。在

Python's documentation about functional programming中,有一个小段落。我将引用以下内容(强调我的):

Python programs written in functional style usually won’t go to the extreme of avoiding all I/O or all assignments; instead, they’ll provide a functional-appearing interface but will use non-functional features internally. For example, the implementation of a function will still use assignments to local variables, but won’t modify global variables or have other side effects.

换句话说,从外表看问题。函数是否正在修改某些全局变量、类变量?它操纵任何状态吗?如果不是,那么它是纯的。根据上面的文档,在内部函数可以分配给局部变量,但重要的是函数不能修改任何面向外部的状态。在


What is modify internal state and make other changes that aren’t visible...?

看下面的一个例子。我们每次调用global_list时都会修改global_list。在

global_list = []

def non_pure_add1_func(x):
    global_list.append(x)
    return x+1

虽然,上述函数可能是幂等的,但它不是纯函数。在

相关问题 更多 >

    热门问题