python中的延迟评估

时间:2010-02-19 05:18:35

标签: python lambda interpreter evaluation

我听说过python中的延迟评估(例如here),它只是指的是只有在使用它们时,解释器如何评估lambdas?或者,这是否是描述由于python的动态设计如何在运行时之前不会捕获许多错误的正确术语?

或者我完全错过了什么?

2 个答案:

答案 0 :(得分:14)

延迟评估是指在需要之前不评估表达式。在大多数语言中,您使用lambda之类的东西来完成这项工作。这是一个人为的例子,展示了这个概念的一部分:

def list_files():
    for fn in os.listdir('.'):
        yield fn, lambda: open(fn, 'r').read()


for fn, body in list_files():
    if fn.endswith('.txt'):
        print body()

这里,list_files返回一堆文件名和一个“thunk”(没有参数的lambda),它返回文件的内容。 “thunk”是延期评估。使用thunks可以分离您的疑虑:

  • for循环不需要知道如何阅读文件,因此list_files可以替换为list_ftp_fileslist_zip_archive
  • list_files函数不需要知道将读取哪些文件。通过thunk,它不必读取每个文件。

在正确的延期评估中,一旦你评估了“thunk”,它就会用一个评估版本替换它自己,所以评估它两次就不会比评估它一次了。还有其他方法可以实现相同的功能,例如使用缓存值的类和对象。

延期评估是Sch​​eme中(相对)常见的习语。在Haskell中,默认情况下会推迟评估,并且您不需要任何语法(有关闭它的特殊语法)。

答案 1 :(得分:8)

Dietrich的答案很好,但我只想补充说,最简单的延期评估形式是if声明:

if True:
  x = 5
else:
  x = y    # huh? what is y?

此代码正确解析并运行,尽管else子句毫无意义 - y未定义。 else子句只被解析 - 所以它在语法上应该是有效的Python。这实际上可以用于一些简单的代码:

if stuff:
   print stuff.contents
else:
   print "no stuff"

在强类型语言中,这不起作用,因为键入stuff.contents要求stuff属于具有contents属性的特定类型。在Python中,由于对if中语句的延迟评估,这不一定是真的。 stuff可以是None,显然没有属性,解释器只需要else子句而不执行第一个。因此,这是有效的Python,甚至是一个成语,使代码更简单。

Reference discussion