今日內容 裝飾器 推導式 模塊【可選】 內容回顧 1. 函數 參數 def (a1,a2):pass def (a1,a2=None):pass 預設參數推薦用不可變類型,慎用可變類型。 def( args, kwargs):pass 註意:位置參數 關鍵字參數 面試題 函數可以做參數【知識點】。 ...
今日內容
- 裝飾器
- 推導式
- 模塊【可選】
內容回顧
- 函數
- 參數
- def (a1,a2):pass
- def (a1,a2=None):pass 預設參數推薦用不可變類型,慎用可變類型。
- def(*args,**kwargs):pass
- 註意:位置參數 > 關鍵字參數
- 面試題
- 函數可以做參數【知識點】。
def func(arg):
arg()
def show():
pass
func(show) 函數的參數傳遞的是什麼?【記憶體地址=引用 or 值】
v = [11,2,33,4]def func(arg): print(id(arg)) # 列表記憶體地址 print(id(v)) # 列表記憶體地址 func(v) # 傳遞的是記憶體地址。
- *args和**kwargs的作用
- 函數可以做參數【知識點】。
- 返回值
- 常見數據類型可以返回
函數也可以返回
def func():
def inner():
pass
return innerv = func()
- 特殊
- 預設沒返回就是None
- return 1,2,3 等價於 return (1,2,3,4,)
- 執行函數
函數不被調用,內部代碼永遠不執行。
def func():
return i
func_list = []
for i in range(10):
func_list.append(func)print(i) # 9 v1 = func_list[4]()#9 v2 = func_list[0]()#9 func_list = [] for i in range(10): # func_list.append(lambda :x) # 函數不被調用,內部永遠不執行(不知道是什麼。) func_list.append(lambda :i) # 函數不被調用,內部永遠不執行(不知道是什麼。) print(func_list)#列表,10個函數的記憶體地址。 print(func_list[2]())#9
執行函數時,會新創建一塊記憶體保存自己函數執行的信息 => 閉包
def base():
return idef func(arg): def inner(): return arg return inner base_list = [] # [base,base,] func_list = [] # [由第一次執行func函數的記憶體地址,內部arg=0 創建的inner函數,有arg=1的inner函數 ] for i in range(10): # i = 0 ,1 base_list.append(base) func_list.append(func(i)) # 1. base_list 和 func_list中分別保存的是什麼? """ base_list中存儲都是base函數。 func_list中存儲的是inner函數,特別要說的是每個inner是在不同的地址創建。 """ # 2. 如果迴圈列印什麼? for item in base_list: v = item() # 執行base函數 print(v) # 都是9 for data in func_list: v = data() print(v) # 0 1 2 3 4 。在for迴圈過程中,func(i)已經執行,for迴圈過程中i的變化值已經被包在其中。
總結:
- 傳參:位置參數 > 關鍵字參數
- 函數不被調用,內部代碼永遠不執行。
- 每次調用函數時,都會為此次調用開闢一塊記憶體,記憶體可以保存自己以後想要用的值。
- 函數是作用域,如果自己作用域中沒有,則往上級作用域找。
- 內置和匿名函數(精英)
- 內置函數
- 匿名函數
- 模塊
- getpass
- random
- hashlib
內容詳細
- 作業題講解
2.裝飾器
v = 1
v = 2
# ########################
def func():
pass
v = 10
v = func
# ##########################
def base():
print(1)
def bar():
print(2)
bar = base
bar()
def func():
def inner():
pass
return inner
v = func()
print(v) # inner函數
# #########################################
def func(arg):
def inner():
print(arg)
return inner
v1 = func(1)
v2 = func(2)
print(v1,v2)
#兩個inner函數記憶體地址。
# #########################################
def func(arg):
def inner():
arg()
return inner
def f1():
print(123)
v1 = func(f1)
v1()
# ###########################################
def func(arg):
def inner():
arg()
return inner
def f1():
print(123)
return 666
v1 = func(f1)
result = v1() # 執行inner函數 / f1含函數 -> 123
print(result) # None
# ###########################################
def func(arg):
def inner():
return arg()
return inner
def f1():
print(123)
return 666
v1 = func(f1)
result = v1() # 執行inner函數 / f1含函數 -> 123
print(result) # 666
def func():
print(1)
v1 = func
func = 666
===========================裝飾器=========
def func(arg):
def inner():
print('before')
v = arg()
print('after')
return v
return inner
def index():
print('123')
return '666'
# 示例一
"""
v1 = index() # 執行index函數,列印123並返回666賦值給v1.
"""
# 示例二
"""
v2 = func(index) # v2是inner函數,arg=index函數
index = 666
v3 = v2()
"""
# 示例三
"""
v4 = func(index)
index = v4 # index ==> inner
index()
"""
# 示例四
index = func(index)
index()
def func(arg):
def inner():
v = arg()
return v
return inner
# 第一步:執行func函數並將下麵的函數參數傳遞,相當於:func(index)
# 第二步:將func的返回值重新賦值給下麵的函數名。 index = func(index)
@func
def index():
print(123)
return 666
print(index)
index=func(index)
index()
裝飾器:在不改變原函數內部代碼的基礎上,在函數執行之前和之後自動執行某個功能。 (之前和之後增加某些功能-func)
應用:
# 計算函數執行時間
import time
def wrapper(func):
def inner():
start_time = time.time()
v = func()
end_time = time.time()
print(end_time-start_time)
return v
return inner
@wrapper
def func1():
time.sleep(2)
print(123)
@wrapper
def func2():
time.sleep(1)
print(123)
def func3():
time.sleep(1.5)
print(123)
func1()
#裝飾器作用,在變動原函數(func)的基礎上,增加原函數的功能(在wrapper里增加)。
#在不改變原函數內部代碼的基礎上,在函數執行之前和之後自動執行某個功能。
總結
- 目的:在不改變原函數的基礎上,再函數執行前後自定義功能。
編寫裝飾器 和應用
# 裝飾器的編寫
def x(func):
def y():
# 前
ret = func()
# 後
return ret
return y# 裝飾器的應用 @x def index(): return 10 @x def manage(): pass # 執行函數,自動觸發裝飾器了 v = index() print(v)
- 應用場景:想要為函數擴展功能時,可以選擇用裝飾器。
- 記住:
- 裝飾器編寫格式
def 外層函數(參數): #參數是函數名
def 內層函數(*args,**kwargs):
return 參數(*args,**kwargs)
return 內層函數 裝飾器應用格式
@外層函數
def index():
passindex()
問題:為什麼要加 *args, **kwargs
- 裝飾器編寫格式
3.推導式
- 列表推導式
基本格式
"""
目的:方便的生成一個列表。
格式:
v1 = [i for i in 可迭代對象 ]
v2 = [i for i in 可迭代對象 if 條件 ] # 條件為true才進行append
"""
v1 = [ i for i in 'alex' ]
v2 = [i+100 for i in range(10)]
v3 = [99 if i>5 else 66 for i in range(10)]def func(): return 100 v4 = [func for i in range(10)] v5 = [lambda : 100 for i in range(10)] result = v5[9]() def func(): return i v6 = [func for i in range(10)] result = v6[5]() v7 = [lambda :i for i in range(10)] result = v7[5]() v8 = [lambda x:x*i for i in range(10)] # 新浪微博面試題 # 1.請問 v8 是什麼? # 2.請問 v8[0](2) 的結果是什麼? # 面試題 def num(): return [lambda x:i*x for i in range(4)] # num() -> [函數,函數,函數,函數] print([ m(2) for m in num() ]) # [6,6,6,6] # ##################### 篩選 ######################### v9 = [i for i in range(10) if i > 5]
- 集合推導式
v1 = { i for i in 'alex' } - 字典的推導式
v1 = { 'k'+str(i):i for i in range(10) }
今日總結
- 裝飾器 (6**)
- 編寫格式:雙層嵌套函數
- 應用格式:@外層函數
- 理解:
變數賦值
def func():
print(1)v1 = func func = 666
- 看看到底return的是什麼?
- 自己 > 上級作用域
- 背會:
@xx # index = xx(index)
def index():
pass
index()
- 推導式(3*)
模塊
import timev = time.time() # 獲取當前時間 time.sleep(2) # 睡2秒