撩課-Python-每天5道面試題-第8天
一. 解釋下什麼是閉包? 有怎樣的場景作用?
-
概念
在函式巢狀的前提下
內層函式引用了外層函式的變數(包括引數)
外層函式, 又把 內層函式 當做返回值進行返回
這個內層函式+所引用的外層變數, 稱為 "閉包" - 標準格式
def test1(a): b = 10 其他函式定義程式碼 def test2(): print(a) print(b) return test2
-
應用場景
外層函式, 根據不同的引數, 來生成不同作用功能的函式 -
案例
根據配置資訊, 生成不同的分割線函式
def line_config(content, length): def line(): print("-"*(length // 2) + content + "-"*(length // 2)) return line line1 =line_config("閉包", 40) line1() line2 = line_config("xxxx", 80) line2()
-
注意事項
-
閉包中, 如果要修改引用的外層變數
需要使用nonlocal 變數宣告
否則當做是閉包內, 新定義的變數 -
當閉包內, 引用了一個, 後期會發生變化的變數時, 一定要注意
函式, 是被呼叫時, 才去確定變數標識所對應的值
-
閉包中, 如果要修改引用的外層變數
二.簡述對裝飾器的理解
-
作用
在函式名以及函式體不改變的前提下, 給一個函式附加一些額外程式碼 - 語法
@裝飾器 def 被裝飾函式(): code
- 案例
完成基本的 發說說, 發圖片 函式
在上述函式的基礎上, 嵌入 身份驗證操作, 只有驗證通過後才可以發說說,發圖片
def checkLogin(func): def inner(): print("登入驗證...") func() return inner # 定義兩個功能函式 @checkLogin def fss(): print("發說說") # 語法糖 寫法 @checkLogin def ftp(): print("發圖片") # ftp = checkLogin(ftp) # 相關的邏輯程式碼 btnIndex = 1 if btnIndex == 1: fss() else: ftp()
"開放封閉"原則
已經寫好的程式碼, 儘可能不要修改
如果想要新增功能, 在原先程式碼基礎上, 單獨進行擴充套件
單一職責
功能保持單一, 不要新增太多的冗餘功能
注意
裝飾器的執行時間, 是立即執行
ofollow,noindex">簡介明瞭有深度的裝飾器教程連結三. 簡述對生成器的理解?
- 生成器
- 是一個特殊的迭代器(迭代器的抽象層級更高)
-
所以, 擁有迭代器的特性
惰性計算資料, 節省記憶體
能夠記錄狀態, 並通過next()函式, 訪問下一個狀態
具備可迭代特性 -
但是, 如果打造一個自己的迭代器, 比較複雜
需要實現很多方法 後續在"面向物件"程式設計中會進行講解
所以, 就有一個更加優雅的方式 "生成器"
- 建立方式
-
生成器表示式
把列表推導式的[] 修改成()
(i for i in range(1, 10000000) if i % 2 == 0) -
生成器函式
函式中包含yield語句
這個函式的執行結果就是 "生成器"
-
產生資料的方式
生成器具備可迭代特性
next()函式 等價於 生成器.next ()
for in
-
關閉生成器
g.close()
後續如果繼續呼叫, 會丟擲StopIteration異常提示
-
注意
如果碰到return
會直接終止, 丟擲StopIteration異常提示
生成器只會遍歷一次
四. 什麼是遞迴函式? 有怎樣的應用場景?
-
體現
- 函式A內部, 繼續呼叫函式A
-
概念
傳遞
迴歸
-
注意事項
- 有傳遞, 一定要有迴歸
- 否則, 就是無限的迴圈呼叫
-
案例
求一個數值的階乘
# 9 # 1 * 2 * 3 * ... 9 # 9! = 9 * 8! #8 * 7! #7 * 6! #.... #1! = 1 # 功能: 如果是不直接知道結果的資料, 就進行分解 9 9 * 8! 8 = # 如果說, 直接知道結果的資料, 就直接返回 1! = 1 def jiecheng(n): if n == 1: return 1 # n != 1 return n * jiecheng(n - 1) result = jiecheng(5) print(result)
五. 函式作用域
-
變數的作用域
變數的作用範圍 , 可操作範圍
-
Python是靜態作用域,也就是說在Python中,變數的作用域源於它在程式碼中的位置;
在不同的位置, 可能有不同的名稱空間
- 名稱空間
- 是作用域的體現形式
- 不同的具體的操作範圍
-
Python-LEGB
L-Local
函式內的名稱空間
作用範圍: 當前整個函式體範圍
E-Enclosing function locals
外部巢狀函式的名稱空間
作用範圍: 閉包函式
G-Global
全域性名稱空間
作用範圍: 當前模組(檔案)
B-Builtin
內建模組名稱空間
作用範圍: 所有模組(檔案)
注意
Python中沒有塊級作用域
塊級作用域
程式碼塊中, 比如 if while for 後的程式碼塊
LEGB規則
按照L -> E -> G -> B 的順序進行查詢
- 基於名稱空間的常見變數型別
-
區域性變數
在一個函式內部定義的變數;
作用域為函式內部
檢視區域性變數
locals() -
全域性變數
在函式外部, 檔案最外層定義的變數
作用域為整個檔案內部
檢視全域性變數
globals()