python嵌套函數作用域怎么解釋
問題描述
直接上代碼
def l(list): def d():return list return d #運行l = l([1,2,3,4])print l()
這個情況是正常的。
問題在于d函數為什么不能傳入list,然后我現在嘗試了一下這個代碼:
def l(list): def d(list):return list return d #運行l = l([1,2,3,4])#提示錯誤print l()#正常print l([1,3,5,7,9])
請問這個怎么解釋呢?我個人理解的是,類似于“繼承”的情況,當d函數沒有參數傳入的情況上,基于父函數的參數,當他需要傳參了,就覆蓋了???
問題解答
回答1:看看LEGB原則,就會明白是怎么回事。https://zhuanlan.zhihu.com/p/...
運行l = l([1,2,3,4])
提示錯誤print l() 這個錯誤是你沒有傳參數。
回答2:原有代碼中:
def l(list): def d(list):return list return d # <-- 這里是返回的一個要傳入一個參數的函數 #運行l = l([1,2,3,4])#提示錯誤print l() # <-- 這里沒有傳入參數報錯,這里的 l 是 返回的閉包 d#正常print l([1,3,5,7,9]) # <-- 這里的 l 已經不是你最初定義的 l 而是 最初 l 中返回的 d
下面的用于說明:你原來代碼中的 l 指向不同:
def l(list): def d(list):return list return d #運行print ’id(l) is {}’.format(id(l))l = l([1,2,3,4])#提示錯誤# print l()#正常print ’id(l) is {}’.format(id(l))print l([1,3,5,7,9])
代碼寫成這樣你可能就理解了:
def l(_list): def d(_l):return _list + _l return d a = l([1,2,3,4])print a([1])
最后說兩點:
不要使用 list 這樣的關鍵字作為變量名
不要覆蓋你的變量名(除非真的有必要)
回答3:樓主需要理解的是: 作用域
case 1: 函數l返回函數d的地址,d只做為返回值,并沒有被調用執行.
In [3]: print(l([1,2,3,4]))<function l.<locals>.d at 0x7f49243ece18>
參數list傳入l,作用域在函數l內,可以被d訪問(注意參數是傳給l的,不是d). 如果要訪問list.如下調用: `
In [2]: print(l([1,2,3,4])()) [1, 2, 3, 4]
相當于:
In [5]: d = l([1,2,3,4]) # 返回d的地址In [6]: d()#調用d,d沒有參數,不需要傳參 Out[6]: [1, 2, 3, 4]
case 2: 同樣l返回d的地址,但此時返回的函數d需要傳參(注意l的參數list和d的參數list是不一樣的).
In [8]: d = l([1,2,3,4])# 返回函數d的地址,參數list此時并沒有用到In [9]: d([5,6,7,8])# 需要參數的函數d Out[9]: [5, 6, 7, 8]
相關文章:
1. javascript - 在top.jsp點擊退出按鈕后,right.jsp進行頁面跳轉,跳轉到login.jsp2. android - 哪位大神知道java后臺的api接口的對象傳到前端后輸入日期報錯,是什么情況?求大神指點3. java - spring-data Jpa 不需要執行save 語句,Set字段就可以自動執行保存的方法?求解4. css3 - 在sublime text里, 如何讓emmet生成的帶前綴css屬性垂直對齊?5. mac連接阿里云docker集群,已經卡了2天了,求問?6. [前端求職必看]前端開發面試題與答案精選_擴展問題7. javascript - js 有什么優雅的辦法實現在同時打開的兩個標簽頁間相互通信?8. javascript - jquery怎么給select option一個點擊時觸發的事件,如圖 如果選擇自定義觸發一個時間?9. css3 - Typecho 后臺部分表單按鈕在 Chrome 下出現靈異動畫問題,求解決10. html - CSS如何處理圖片縮放問題?
