day11 閉包函式和裝飾器
1.函式不是新知識點 主要是學習函式的用法
在面向物件程式設計中,一切皆物件,函式也不例外
具體的表現
1.函式可以引用
2.函式可以作為函式的引數
3.函式可以作為函式的返回值
4.可以被儲存到容器型別中
def func1():
pass
a=func()
def func(func):
func()
func2(func1)
def func3():
return func1
def fun5():
print('func5 run')
li2 = [func5]
li2[2]()
2.函式的巢狀
1.定義的巢狀,在一個函式的定義內再定義函式
def f1():
print('f1')
def f2():
print('f2')
f2()
f1()
2.巢狀的呼叫,先定義好函式,在其他函式體內呼叫
def f1():
print('f1')
def f2():
print('f2')
f1()
f2()
名稱空間就是一個字典,專門儲存名稱的空間,不僅儲存名字,還要知道記憶體地址
名稱空間分類
1.內建名稱空間,儲存直譯器的一些名稱與值的對應關係
(python 直譯器啟動時建立,所有程式碼全部執行完畢,關閉直譯器時銷燬)
2.全域性名稱空間 檔案級別的名稱,只要你的名字的定義是頂著最左邊寫的就是全域性空間
(執行py檔案時建立全域性名稱空間,所有檔案中的程式碼全部執行完畢,關閉直譯器時銷燬)
除了內建和函式內,都在全域性名稱空間中
3.區域性名稱空間:只要是在函式內的名稱都是區域性的
(呼叫函式時建立,函式執行完畢就銷燬)
名稱空間的載入順序
內建-》全域性-》區域性
名稱的查詢順序
區域性-》全域性-》內建的
3.作用域
域就是範圍的意思
全域性名稱空間和內建名稱空間,在使用上沒有區別
區域性的和全域性/內建的就有區別了:區域性定義的只能在區域性使用
給三個空間劃分範圍
全域性的內建的可以劃分為同一個範圍
global表示全域性範圍,就是所謂的全域性作用域
區域性的單獨劃分為一個範圍
local區域性作用域
檢視全域性作用域的內容globals()
檢視區域性作用域的內容 注意,你在全域性作用域使用locals看到的就是全域性的內容,域glaobals沒有區別
函式locals()
a = 'aasdasd'
print()
檢視全域性作用域中的內容
print(dir(globals()["__builtins__"]))
檢視區域性作用域中的內容 注意 你在全域性中使用locals 看到的就是全域性的內容,與globals沒有區別
關鍵字
global #宣告要使用全域性中的變數名
nonlocal #明確宣告 要使用上一層的a,如果上一層沒有,則找上上層,但是注意,不能找全域性中的
age=18
def func2():
#明確宣告 要使用全域性中的age
global age
age = 19
print(age)
fun2()
print(age) #因為區域性名稱空間中用了global,所以直接用的全域性變數age,直接被修改了
def f1():
#age = 19
def f2():
nonlocal age #會報錯,因為往上層找沒有找到age
print(age)
f2()
f1()
print(age)
4.閉包函式
如下就是一個閉包函式
def fun1():
age = 18
def inner():
print('hello')
print(age)
在返回這個內部的函式時 不是單純的返回函式 還把函式中訪問的區域性名稱一起打包了
相當於將內部函式域訪問的資料打包在一起了 閉包這個名字就是這麼得來的
return inner
f=fun1()
函式的作用域在定義時就固定了,與呼叫的位置沒有關係
閉包函式的模版
def fun2():
a = 1
b=10
def inner():
print(a)
print(b)
print(c)
return inner
f = fun2()
#__closure__用於訪問閉包函式 打包的資料
什麼是閉包函式
1.定義在另一個函式內的函式
2.內部的函式訪問了外部的名稱(資料) 注意 不包含全域性的
5.裝飾器
什麼是裝飾 給一個已有的物件(一個函式)新增新的功能
為什麼要裝飾:為了 增強功能
器:指一個工具,在python中,值得是具備某個功能的函式
簡單的說:裝飾器是一個用於其他函式增加功能的函式
開閉原則
指的是對擴充套件開放,對修改封閉(可以新增新功能,但不能修改原始碼和程式碼的呼叫方式)
使用者程式的使用者
用框架的使用者
print(time.time())返回一個時間戳,指的是1970年1月1日(unix元年)到現在一共經過的秒數
mac是Linux 核心,linux是unix的一個分支
裝飾器和閉包函式的關係:裝飾器是一種設計程式碼的套路(不修改原始碼和呼叫方式的情況下,增加功能)
要完成裝飾器就需要使用閉包函式
裝飾器不是閉包,閉包也不是裝飾器,只是通過閉包函式完成裝飾器的設計
把舊功能的函式傳進閉包函式,加好新功能,返回閉包函式,這樣在下次呼叫時,其實是在呼叫改版的舊函式
裝飾模式
def otter(func):
def inner():
在呼叫原始函式前,新增新功能
func()
return inner
download = otter(download)
download()
既遵守了開閉原則,又添加了新功能