python中的延迟计算

2024-05-23 20:07:31 发布

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

我听说过python中的延迟求值(例如here),它是指lambda仅在使用时如何由解释器求值吗?或者这是描述由于python的动态设计,它在运行时之前不会捕获许多错误的恰当术语吗?

还是我完全错过了什么?


Tags: lambdahere错误动态解释器术语
2条回答

延迟求值是指在需要表达式之前不求值。在大多数语言中,您使用类似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)返回文件内容。“砰”的一声是延期的评估。使用thunks可以分离您的关注点:

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

在适当的延迟评估中,一旦您评估了“thunk”,它将替换为一个已评估的副本,因此评估两次将不比评估一次多。还有其他方法可以完成相同的任务,例如使用缓存值的类和对象。

延迟评估是Scheme中(相对而言)一个常见的习惯用法。在Haskell中,默认情况下计算是延迟的,您不需要任何语法来完成它(有特殊的语法来关闭它)。

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

相关问题 更多 >