2024-05-23 20:07:31 发布
网友
我听说过python中的延迟求值(例如here),它是指lambda仅在使用时如何由解释器求值吗?或者这是描述由于python的动态设计,它在运行时之前不会捕获许多错误的恰当术语吗?
还是我完全错过了什么?
延迟求值是指在需要表达式之前不求值。在大多数语言中,您使用类似lambda的东西来实现这一点。下面是一个精心设计的示例,它展示了部分概念:
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可以分离您的关注点:
list_files
list_ftp_files
list_zip_archive
在适当的延迟评估中,一旦您评估了“thunk”,它将替换为一个已评估的副本,因此评估两次将不比评估一次多。还有其他方法可以完成相同的任务,例如使用缓存值的类和对象。
延迟评估是Scheme中(相对而言)一个常见的习惯用法。在Haskell中,默认情况下计算是延迟的,您不需要任何语法来完成它(有特殊的语法来关闭它)。
Dietrich的回答很好,但我只想补充一点,延迟评估的最简单形式是if语句:
if
if True: x = 5 else: x = y # huh? what is y?
尽管else子句没有意义-y是未定义的,但这段代码可以正确地解析和运行。else子句只被解析,因此它在语法上应该是有效的Python。这实际上可以用于一些简单的代码:
else
y
if stuff: print stuff.contents else: print "no stuff"
在强类型语言中,这是行不通的,因为键入stuff.contents需要stuff是具有contents属性的特定类型。在Python中,由于if中语句的延迟求值,这不一定是真的。stuff可以是None,它显然没有属性,解释器只接受else子句而不执行第一个。因此,这是有效的Python,甚至是一个习惯用法,它使代码更简单。
stuff.contents
stuff
contents
None
Reference discussion
延迟求值是指在需要表达式之前不求值。在大多数语言中,您使用类似
lambda
的东西来实现这一点。下面是一个精心设计的示例,它展示了部分概念:这里,
list_files
返回一组文件名和一个“thunk”(没有参数的lambda)返回文件内容。“砰”的一声是延期的评估。使用thunks可以分离您的关注点:list_files
可以替换为list_ftp_files
或list_zip_archive
。list_files
函数不需要知道将读取哪些文件。使用thunks,它不必读取每个文件。在适当的延迟评估中,一旦您评估了“thunk”,它将替换为一个已评估的副本,因此评估两次将不比评估一次多。还有其他方法可以完成相同的任务,例如使用缓存值的类和对象。
延迟评估是Scheme中(相对而言)一个常见的习惯用法。在Haskell中,默认情况下计算是延迟的,您不需要任何语法来完成它(有特殊的语法来关闭它)。
Dietrich的回答很好,但我只想补充一点,延迟评估的最简单形式是
if
语句:尽管
else
子句没有意义-y
是未定义的,但这段代码可以正确地解析和运行。else
子句只被解析,因此它在语法上应该是有效的Python。这实际上可以用于一些简单的代码:在强类型语言中,这是行不通的,因为键入
stuff.contents
需要stuff
是具有contents
属性的特定类型。在Python中,由于if
中语句的延迟求值,这不一定是真的。stuff
可以是None
,它显然没有属性,解释器只接受else
子句而不执行第一个。因此,这是有效的Python,甚至是一个习惯用法,它使代码更简单。Reference discussion
相关问题 更多 >
编程相关推荐