Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中的延迟求值_Python_Lambda_Interpreter_Evaluation - Fatal编程技术网

python中的延迟求值

python中的延迟求值,python,lambda,interpreter,evaluation,Python,Lambda,Interpreter,Evaluation,我听说过python中的延迟求值(例如),它只是指只有在使用lambda时,解释器才会对其求值吗?或者,这是描述由于python的动态设计,它在运行时之前不会捕获许多错误的恰当术语吗 还是我完全遗漏了什么?延迟求值是指直到需要时才对表达式求值。在大多数语言中,您使用类似于lambda的东西来实现这一点。下面是一个人为的例子,展示了部分概念: def list_files(): for fn in os.listdir('.'): yield fn, lambda: ope

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


还是我完全遗漏了什么?

延迟求值是指直到需要时才对表达式求值。在大多数语言中,您使用类似于
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\u files
返回一组文件名和一个“thunk”(lambda,不带参数),返回文件内容。“thunk”是一个延迟评估。使用thunks可以分离您的关注点:

  • for循环不需要知道如何读取文件,因此
    list\u文件
    可以替换为
    list\u ftp\u文件
    list\u zip\u存档
  • 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,甚至是一种使代码更简单的习惯用法


lambda延迟,但要注意存储,因为它们不会像您当前拥有的那样捕获fn:。还有一个警告:。这是一个很好的观点,也是我在用Python编写代码时远离lambda的原因之一。这就是为什么我更喜欢内联函数+
functools。要冻结参数,请使用partial
:我认为您在第二个示例中混淆了类型系统和惰性计算。“强”类型语言可以使用惰性求值来完成巧妙的操作。例如,Haskell有一个非常强大的静态类型系统,其中包含大量惰性评估!与Python不同,
if-then-else
必须进行类型检查,但除此之外,计算是延迟的。例如,如果为True,则可以编写
,如果为True,则可以编写5个else undefined
,这样编译和运行很好(结果是5,正如预期的那样)。您的
if-else
在Python中工作,即使它在静态语言中没有键入check,这与评估策略无关。