撩課-Python面試寶典-第八篇
阿新 • • 發佈:2018-11-23
一. 解釋下什麼是閉包? 有怎樣的場景作用?
- 概念
在函式巢狀的前提下
內層函式引用了外層函式的變數(包括引數)
外層函式, 又把 內層函式 當做返回值進行返回
這個內層函式+所引用的外層變數, 稱為 “閉包” - 標準格式
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()
"開放封閉"原則
已經寫好的程式碼, 儘可能不要修改
如果想要新增功能, 在原先程式碼基礎上, 單獨進行擴充套件
單一職責
功能保持單一, 不要新增太多的冗餘功能
注意
裝飾器的執行時間, 是立即執行
簡介明瞭有深度的裝飾器教程連結
三. 簡述對生成器的理解?
- 生成器
- 是一個特殊的迭代器(迭代器的抽象層級更高)
- 所以, 擁有迭代器的特性
惰性計算資料, 節省記憶體
能夠記錄狀態, 並通過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()