Python fib(n)是纯函数吗?
Python fib(n)是纯函数吗?,python,multithreading,immutability,purely-functional,Python,Multithreading,Immutability,Purely Functional,fib(n)计算第n个斐波那契数: def fib(n): """Compute nth Fibonacci number""" pred, curr = 1, 0 # 0 is 0th Fibonacci number k = 0 # curr is kth Fibonacci number while k < n: pred, curr = curr, pred + curr k = k +
fib(n)
计算第n个斐波那契数:
def fib(n):
"""Compute nth Fibonacci number"""
pred, curr = 1, 0 # 0 is 0th Fibonacci number
k = 0 # curr is kth Fibonacci number
while k < n:
pred, curr = curr, pred + curr
k = k + 1
return curr
def fib(n):
“”“计算第n个斐波那契数”“”
pred,curr=1,0#0是第0个斐波那契数
k=0#curr是第k个斐波那契数
当k
它不会对程序的其余部分产生副作用。它是线程安全的
尽管状态(
k
,curr
,pred
)在本地进行了修改,但在讨论外部世界时,Isfib(n)
a?纯功能发挥作用。如果在调用函数之前和之后拍摄所有对象的快照,则这两个快照应该相同
您所说的函数是纯函数,因为它不修改程序的状态或任何其他部分。在下列情况下,您的函数不是纯函数:
- 如果使用
关键字修改另一个变量global
- 如果它是一个对象的方法,并且它更改了对象的内部状态
- 如果它以任何方式发生变异
fibn
将始终产生相同的输出。这一点很清楚。而且,正如您所说,被修改的变量只存在于函数的局部范围内,因此在函数之外没有语义上可观察到的副作用。唯一需要说明的是(1)的推论是函数总是终止的。有一个while
循环,但是如果给定任何有限的n
,则证明您的while
循环将终止是微不足道的。因此,根据提供的定义,您的函数是纯函数
现在,我假设您将“必须是整数”列为先决条件。如果您不将此列为需求,那么我可以生成一个类,其排序方法总是使其大于任何
k
值,从而强制执行无限循环。无限循环有一个非常明显的副作用:在这种情况下,您的程序往往不会终止。但是,如果您将注意力限制在整数输入上,那么您的函数是纯函数。为什么它不是纯函数?@Andreiciara在编写纯函数时,我是否需要避免可变对象的突变(k
,curr
,pred
),正如wiki中提到的:结果的评估不会导致任何语义上可观察的副作用或输出,例如可变对象的变异k
,curr
,以及pred
,都不是可变对象。而是将不同的对象绑定到函数命名空间中的相同名称。即使您确实使用了可变对象,这仍然是一个纯函数,因为它在调用它的程序的上下文中不是有状态的,并且不会影响它未创建的任何对象的状态。您需要避免可变对象的突变,因为该对象来自外部世界。你可以用你的私有一次性变量做任何你想做的事情。正如@PatrickHaugh所提到的,k、curr和pred是不可变的。@PatrickHaugh我理解您的观点,即在python世界中,int
type对象是不可变的。但我们不要谈这个。考虑到伪代码,它们是可变的。n
、k
、pred
、curr
都在本地范围内。为什么变异的n
使其不纯?如果它变异了n…,则为“Re”。但是,除非n是一个数字,否则显示的函数没有任何意义。数字不是一成不变的吗?只要你遵守规则,它们是一成不变的,但你绝对可以改变它们(不推荐)。请看这里被接受的答案,我没有得到你的最后一段。除了整数还有什么?Python是动态类型的。我可以传入字符串、文件句柄或任何类的实例。为了使函数成为纯函数,它需要实际生成零个或多个值,因此如果循环最终是无限的,那么函数就不能成为纯函数。函数不终止(无限循环)与纯函数有关系吗?添加前置条件是编写抽象(在本例中为函数)的良好实践的一部分。我不认为证明是琐碎的。在Python中,您确实不需要担心整数溢出,并且您已经包含了“必须是整数”,这很好,因为像1e16
这样的浮点将导致无限循环。证明的困难在于确保你已经涵盖了所有的极端情况,比如负整数。你的最后一段提到的是不同的主题