131、下面這段代碼的輸出結果將是什么?請解釋。
def multipliers():
return [lambda x : i * x for i in range(4)]
print [m(2) for m in multipliers()]
上面代碼輸出的結果是[6, 6, 6, 6] (不是我們想的[0, 2, 4, 6])。
上述問題產生的原因是Python閉包的延遲綁定。這意味着內部函數被調用時,參數的值在閉包內
進行查找。因此,當任何由multipliers()返回的函數被調用時, i的值將在附近的范圍進行查找。那時,
不管返回的函數是否被調用,for循環已經完成,i被賦予了最終的值3。
因此,每次返回的函數乘以傳遞過來的值3,因為上段代碼傳過來的值是2,它們最終返回的都是6。下面是解決這一問題的一些方法。
一種解決方法就是用Python生成器。
def multipliers():
for i in range(4): yield lambda x :
i * x
另外一個解決方案就是創造一個閉包,利用默認函數立即綁定。
def multipliers():
return [lambda x, i=i : i * x for i in range(4)]
132、什么是lambda函數?它有什么好處?寫一個匿名函數求兩個數的和?
"""
lambda 函數是匿名函數;使用 lambda 函數能創建小型匿名函數。這種函數得名於省略了用 def
聲明函數的標准步驟;
"""
# 答案
f = lambda x,y:x+y
print(f(2017,2018))
133、說說python中裝飾器、迭代器的用法;描述下dict的items()方法與iteritems()方法的不同;
# 答案
'''
裝飾器是指對函數執行過程,做一些擴展,甚至可以更改本身函數的執行迭代器是指遵循迭代器協議的對象,這類對象在被for循環時,每次迭代生成下一個項,不用一開始就生成整個列表在python3中不存在iteritems,items方法返回可迭代對象在python2中items()返回[(key,value)]的列表對象,iteritems()返回迭代器對象,iteritems()循環時不可以增刪dict的內容
'''
134、def(a, b=[])這種寫法有什么陷阱?
# 答案
'''
函數的第二個默認參數是一個list,當第一次執行的時候實例化了一個list,第二次執行還是用第一次執行的時候實例化的地址存儲,所以三次執行的結果就是 [1, 1, 1] ,想每次執行只輸出[1] ,默認參數應該設置為None。
'''
135、如何判斷一個值是函數還是方法?
from types import MethodType,FunctionType
print(isinstance('1', FunctionType)) # False
print(isinstance(lambda x:x, FunctionType)) # True
