閉包函數、裝飾器

閉包函數
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())
View Code

須要注意的是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()
View Code

函數參數的問題
無參函數和有參函數均可以直接調用???
函數能夠接收任意數量的參數

裝飾器的模板

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()
View Code

注:語法糖在書寫的時候應該與被裝飾對象牢牢挨着 二者之間不要有空格

相關文章
相關標籤/搜索