函式物件,名稱空間和作用域以及閉包函式和裝飾器
重點:函式func() 兩層含義:
第一層: func 指函式物件,指向記憶體地址
第二層: 括號表示觸發函式功能
一. 函式物件(可以理解為函式名):在面對物件中,一切皆物件
具體體現:1.函式可以引用
2.可以作為函式的引數
3.可以作為函式返回值
4.可以被儲藏在容器中
二. 函式巢狀: 在一個函式中呼叫了另一個函式
巢狀:在一個函式中定義了另一個函式,定義在內部的函式只能在函式內部使用。
三. 名稱空間:儲存名字和記憶體地址關係的空間
分類:1. 內建名稱空間: 儲存直譯器自帶的一些名稱與值的對應關係(print, len, max, min,pop 等)
在直譯器啟動時建立
2. 全域性名稱空間:檔案級別的名稱(除了內建和函式內的都為全域性)
在執行py 檔案時建立,所有檔案程式碼執行完畢結束
3. 區域性名稱變數:在內部函式內的名稱。
呼叫函式時建立,函式執行完銷燬
比較: 載入順序: 內建變數 ===> 全域性變數====> 區域性變數
查詢順序: 區域性變數===> 全域性變數 ====> 內建變數
四. 作用域: 域指範圍: 函式的作用域在定義時就固定了,與呼叫為止無關
全域性名稱空間和內建的名稱空間在使用上沒有什麼本質區別, 而區域性名稱只能區域性使用
global: 定義全域性變數,其變數可以在全域性範圍內使用
local: 區域性作用域
globals(): 以字典型別返回當前位置的全部全域性變數
dir() : 不帶引數時返回當前範圍內的變數,方法和定義的型別列表,帶引數時,返回引數的屬性方法列表。 ???
locals() : 檢視區域性作用域中的內容(相對概念)
global a:明確要使用全域性中的變數 a
nonlocal a: 使用上一層中的a, 如果上一層沒有就在上上層找,找到為止,但不表示使用全域性變數
四. 閉包函式:滿足兩個條件
條件一: 定義在另一個函式中
條件二: 在內部的函式中使用了外部的名稱(也就是資料值)
重點: 在返回內部函式時,不是單純的返回函式,還把函式中訪問到的區域性名稱一起打包了
相當於將內部函式與訪問的資料打包在一起了
__closure__用於訪問閉包時打包的資料 print(f.__closure__[0].cell_contents)
如果為全域性變數沒必要包走,外部可直接訪問
def fun1(): name='iris' def inner(): print(name) print('hello') return inner f=fun1() # f 就是inner f()
五. 裝飾器:在不修改原始碼和呼叫方式的條件下為其他函式增加功能的函式
特點:開閉原則(對擴充套件開放,對修改封閉)
裝飾器通過閉包函式實現
#原始碼: def download(): print('開始下載') time.sleep(2) print('下載結束') download() # 為原始碼加上統計開始時間和結束時間並計算總耗時的功能 # 方法一:修改原始碼方法 import time def download(): start_time=time.time() print('開始下載') time.sleep(2) print('下載結束') end_time=time.time() print('下載耗時',(end_time-start_time)) download() # 方法二:修改呼叫方式 import time def download2(): start_time=time.time() download() end_time = time.time() print('下載耗時',(end_time-start_time)) download2() # 方法三:裝飾器 def download(): print('開始下載') time.sleep(2) print('下載結束') def outter(func): def inner(): start_time=time.time() func() end_time=time.time() print('下載耗時', (end_time-start_time)) return inner import time download=outter(download) download()
六. 時間戳: time.time()
用秒錶示當時的時間,指從1970年一月一日零點零分到現在經過的秒數。