我聽說過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中工作與評估策略無關。 –