我听说过python中的延迟评估(例如here),它仅仅指的是lambdas如何仅在使用它时才被解释器评估?或者这是一个合适的术语来描述,由于python的动态设计,它不会在运行时捕获许多错误?Python中的延迟评估
或者我完全错过了一些东西?
我听说过python中的延迟评估(例如here),它仅仅指的是lambdas如何仅在使用它时才被解释器评估?或者这是一个合适的术语来描述,由于python的动态设计,它不会在运行时捕获许多错误?Python中的延迟评估
或者我完全错过了一些东西?
迪特里希的回答是一个很好的,但我只想补充一点,推迟评价的最简单的形式是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
的东西来完成此项工作。下面是显示概念的一部分,一个人为的例子:
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”是延期评估。使用的thunk允许你分开你的顾虑:for循环不需要知道如何读文件
list_files
可以用list_ftp_files
或list_zip_archive
更换。list_files
函数不需要知道哪些文件将被读取。使用thunk时,它不必读取每一个文件。在正确的延期评估中,一旦您评估了“thunk”,它将用评估副本替换自己,因此评估两次将不会比评估一次更好。还有其他方法可以完成同样的事情,例如缓存值的类和对象。
延期评估是Scheme中一个(相对)常见的习惯用法。在Haskell中,评估是默认推迟的,你不需要任何语法来完成它(有特殊的语法来关闭它)。
拉姆达被推迟,但要小心保管,因为他们不捕捉FN,你目前有他们:http://codepad.org/fXfIj364。另一个警告:http://codepad.org/poXS7nc2。 – 2010-02-19 05:50:48
这是一个很好的观点,也是我在Python编程时远离lambda的原因之一。 –
这就是为什么我更喜欢内联函数+'functools.partial'来冻结参数:http:// codepad。org/fwxLbl7l – schlamar
我觉得你在第二个例子中混淆了类型系统和懒惰评估。 “强烈”类型的语言可以使用懒惰评估来做巧妙的技巧。例如。 Haskell有一个非常强大的静态类型系统,有很多懒惰的评估!与Python不同,'if-then-else'必须进行类型检查,但除此之外,评估是延迟的。例如,你可以编写'如果True True then 5 undefined',并且编译并运行得很好(结果如预期的那样是5)。即使没有用静态语言进行类型检查,你的'if-else'在Python中工作与评估策略无关。 –