閉包函數
1.閉:定義在函數內部的函數
2.包:內部函數引用了外部函數做用域的名字python
閉包函數:只須要傳一次參,下面不管在哪用到,直接拿那個名字就能夠了閉包
特色:只給內部傳參,須要什麼傳什麼,永遠不會變ide
def outter(): #先定義一個outter函數 x = 111 def inner(): print(x) return inner res = outter() # res就是inner函數內存地址 def func(): x = 333 res() func()
給函數體傳值的第一種方式 :傳參,直接傳遞數據函數
def index1(username): print(username)
給函數體傳參的第二種方式 閉包(包起來,我給你)工具
def outter(x,y): # x = 1 # y = 40 def my_max(): if x > y: return x return y return my_max res1 = outter(1,40) # res就是my_max函數的內存地址 print(res1()) print(res1()) print(res1()) res2 = outter(90,200) print(res2()) print(res2()) print(res2()) print(res2()) print(res2()) print(res2())
須要注意的是url
def outter (x,y) 與 def outter(): x = 1 y = 10 這兩種本質是同樣的,都是在outter裏面綁定兩個名字,產生兩個值
import requestsspa
第一個直接給函數傳參code
url1 = 'https://www.baidu.com' url2 = '...' def my_get(url): response = requests.get(url) if response.status_code == 200: print(len(response.text)) my_get(url1) my_get(url1) my_get(url1) my_get('https://www.baidu.com') my_get('https://www.baidu.com') my_get('https://www.baidu.com')
第二種給函數傳參的方式 閉包對象
def outter(url):
# url = 'https://www.jd.com'
def my_get():
response = requests.get(url)
if response.status_code == 200:
print(len(response.text))
return my_get
my_jd = outter('https://www.jd.com')
my_jd()
my_jd()
my_baidu = outter('https://www.baidu.com')
my_baidu()
my_baidu()
my_baidu()
my_baidu()
my_baidu()
裝飾器:
器:就是一個工具
裝飾:給被裝飾對象添加新的功能blog
爲何要用裝飾器
開放封閉原則:
開放:對擴展開放
封閉:對修改封閉
裝飾器(可調用對象)必須遵循的兩個原則:
1.不改變被裝飾對象源代碼
2.不改變被裝飾對象(可調用對象)調用方式
def index():
pass
index()
如何用
"""
import time #統計時間
print(time.time())
#1562812014.731474 時間戳 當前時間距離1970-1-1 00:00:00相差的秒數
#1970-1-1 00:00:00是Unix誕生元年
time.sleep(3) # 讓cpu誰三秒 讓你的程序暫停三秒
print('FBI warning!')
簡單版本裝飾器
1.統計index函數執行的時間
import time def index(): time.sleep(3) print('開業了') start = time.time() index() end = time.time() #cpu運行代碼的時候速度是很是快的,代碼與代碼之間距離的時間特別的短, print('index run time:%s'%(end-start))
1.統計index函數執行的時間
import time def index(): time.sleep(3) print('開業了') def outter(func): #func = index函數的內存地址 # func = index def get_time(func): #func=index函數 start = time.time() func() #func=index函數內存地址() 直接調用 運行結束時間 end = time.time() #運行結束時間 print('index run time:%s'%(end-start)) return get_time # res = outter(index) #res變量名 想等於什麼就是什麼 # res() index = outter(index) #函數名只要加括號,優先級最高 outter(最開始的index函數內存地址) #index指向get_time函數的內存地址 index()
升級版裝飾器
import time def index(): time.sleep(3) print('開業了') def login(name): #形參是位置形參 time.sleep(1) print('%s is sb'%name) def outter(func): # func = index def get_time(*args,**kwargs): #func = login函數的內存地址 start = time.time() func(*args,**kwargs) #args = ('egon',) kwargs={} end = time.time() print('index run time:%s'%(end-start)) return get_time # res = outter(index) # res() login = outter(login) #outter(最原始的login函數的內存地址) login是get_time login('egon') index = outter(index) #最原始的index函數 index()
函數參數的問題
無參函數和有參函數均可以直接調用???
函數能夠接收任意數量的參數
裝飾器的模板
def outter(func): def inner(*args,**kwargs): print('執行被裝飾函數以前 你能夠作的操做') res = func(*args,**kwargs) print('執行被裝飾函數以後 你能夠作的操做') return res return inner
裝飾器語法糖
@outter #本質是在最前面
@的工做原理:固定語法會將緊挨着它下面的可調用的名字當作它的參數自動傳入,直接執行
例如:
index = outter(index)
(自動outter())
mport time def outter(func): # func = 最原始的index函數的內存地址 def get_time(*args, **kwargs): start = time.time() res = func(*args, **kwargs) # 最原始的login函數的內存地址() 直接調用 func('egon') end = time.time() print('func run time:%s'%(end-start)) return res return get_time # login = outter(login) # outter(最原始的login函數的內存地址) # index = outter(index) # home = outter(home) @outter # index = outter(index) outter(最原始的index的函數的內存地址) def index(): time.sleep(3) print('澳門最大線上賭場開業啦 性感tank在線發牌!') return 'index' # res1 = index() @outter # login = outter(login) def login(name): time.sleep(1) print('%s is sb'%name) return 'login' # res = login('egon') @outter # home = outter(home) def home(*args,**kwargs): time.sleep(1) return 'home' # login = outter(login) # outter(最原始的login函數的內存地址) # index = outter(index) # home = outter(home) index() login('egon') home()
注:語法糖在書寫的時候應該與被裝飾對象牢牢挨着 二者之間不要有空格