python遲邦定

1.綁定

    將函數體和函數調用關聯起來,就叫綁定html

2.遲綁定

    在程序運行以前(也就是編譯和連接時)執行的綁定是早綁定,遲綁定(late binding)是發生在運行時。python

3.實例說明

def outer():
    return [lambda x: x*i for i in range(3)]
f1, f2, f3 = outer()
print f1(1)
print f2(1)
print f3(1)
 
>>> 2
>>> 2
>>> 2

 

咋一看,上面輸出的值貌似和本身想的並不一致,爲何會出現這個問題,這就是python的遲綁定致使的,閉包中的i值只有在調用匿名函數的時候纔會去查詢,這就致使了當你在調用f1,f2,f3的時候此時i的值已變成2,因此它們的輸出結果都是同樣的。閉包

咱們再來看看這個問題的變形。函數

#狀況一
l = [lambda x: x*i for i in range(3)]
f1, f2, f3 = l
print f1(1),f2(1),f3(1)
 
#狀況二
l = [lambda x: x*i for i in range(3)]
for f in l:
    print f(1)
 
#狀況三
l = (lambda x: x*i for i in range(3))
f1, f2, f3 = l
print f1(1),f2(1),f3(1)
 
#狀況四
l = (lambda x: x*i for i in range(3))
for f in l:
    print f(1)

狀況一:上面這四種狀況的輸出以下:post

2 2 2spa

狀況二:
2
2
2code

狀況三:
2 2 2htm

狀況四:
0
1
2blog

對於狀況一和狀況二,沒什麼好說的,上面已經說過了,緣由在於python的遲綁定。it

可是,爲何會有狀況三和狀況四這種情形發生呢?

首先咱們應該知道python生成器的表達式,相似於列表推導,只不過是圓括號,

(lambda x: x*i for i in range(3))實際上是一個生成器,咱們先說一下爲何狀況四和上面三種都不同,生成器只有在調用next()時纔會執行下去,因此在對這個生成器進行for迭代時,迭代一次,i的值變化一次,因此輸出結果纔會有0,1,2的變化。

爲何狀況三沒有這個變化呢?

l = (lambda x: x*i for i in range(3)),f1, f2, f3 = l,在對f1,f2,f3進行賦值時,已所有迭代完了,此時i的值爲2,因此會出現輸出值全是2的狀況。

相關文章
相關標籤/搜索