Python 函数式编程和并发,当执行任务之间没有任何依赖关系时并发处理最为高效。并发(或并行)编程开发的最大难点在于协调对共享资源的更新。
在遵循函数式设计模式的前提下,我们往往避免设计状态化的程序。函数式设计应当尽量减少或消除对共享对象的并发更新。如果可以设计出以惰性求值和非严格求值为核心的软件,那么同样可以设计出并发求值的软件。这样便能实现高度并行的设计,其中大多数工作都可以并发完成,而计算之间的交互则很少或根本没有。
编程的核心是运算之间的相互依赖。在表达式2*(3+a)
中,必须先计算子表达式(3+a)
。表达式的最终值取决于两个运算的先后顺序。
在处理集合对象时,经常会遇到这样的情况:集合中各项的处理顺序无关紧要。考虑以下两个例子:
x = list(func(item) for item in y)
x = list(reversed([func(item) for item in y[::-1]]))
即使这两个命令对表达式func(item)
的求值顺序是相反的,结果仍是相同的。这只有在每一次func(item)
的求值都是独立的且没有副作用的情况下才可行。
下面的命令片段效果也相同:
import random
indices = list(range(len(y)))
random.shuffle(indices)
x = [None]*len(y)
for k in indices:
x[k] = func(y[k])
上述示例中的求值顺序是随机的。由于对func(y[k])
的每一次求值都是相对独立的,因此求值顺序并不重要。许多算法都允许这种非严格求值。