闭包函数,装饰器

一、闭包函数

闭:定义在函数内部的的函数

包:内部函数引用了外部函数作用域的名字

def outter():
    x = 111
    def inner():
        print(x)
    return inner
res = outter()

在这样的情况下x,如果在全局空间中,对x再怎么赋值。x永远是111,即为封闭,而x是在内部函数中,获取了外层函数的赋的值,即为包。

函数传参的两种方法:

第一种:直接给函数传参

import  requests
url1 = 'https://www.baidu.com'
def my_get(url):
    response = requests.get(url)
    if response.status_code == 200:
        print(len(response.text))
my_get(url1)

第二种:闭包方式

def outter(url):
    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')

二、装饰器

器:就是一个工具

装饰:给被装饰对象添加新的功能

为什么要用装饰器:

开放封闭原则:

开放:对扩展开放

封闭:对修改封闭

装饰器(可调用对象)必须遵循的两个原则:

1.不改变装饰对象源代码

2.不改变装饰对象(可调用对象)调用方式

def index():
    pass
index()

1.统计index函数执行的时间

我们从简单的装饰器开始慢慢进阶

 1 #装饰器1.0
 2 import time
 3 def index():
 4     time.sleep(3)
 5     print('今天的鸡哥又是格外的帅气!')
 6 def outter(func):
 7     def get_time():
 8         start = time.time()
 9         func()
10         end = time.time()
11         print('index run time:%s'%(end - start))
12     return get_time
13 index = outter(index)
14 index()

简单标个步骤流程:

但是简单装饰器有个弊端,就是它的内部函数是无参的,但凡你外部调用函的数中含有参数,内部函数就会报错,然后我们在原基础上,稍作修改得到一个装饰器的进阶版本。

#装饰器2.0 
1
import time 2 def index(): 3 time.sleep(3) 4 print('今天的鸡哥又是格外的帅气!') 5 def joke(name): 6 time.sleep(1) 7 print('今天的%s只能做衬托...'%name) 8 def outter(func): 9 def get_time(*args,**kwargs): #进行打包 10 start = time.time() 11 func(*args,**kwargs)#进行打散 12 end = time.time() 13 print('index run time:%s'%(end - start)) 14 return get_time 15 index = outter(index) 16 index() 17 joke = outter(joke) 18 joke('tank')

虽然上面我们已经弥补了装饰器1.0的缺陷,但是有个问题,index = outter(index) 看起来是不是有那么一些绕,虽然我们这边用到了“以假乱真”这种办法,但是有没有比这种方法表达更好看的办法呢,那么就有了装饰器语法糖

# 装饰器最终版本
1
import time 2 def outter(func): 3 def get_time(*args,**kwargs): #进行打包 4 start = time.time() 5 func(*args,**kwargs)#进行打散 6 end = time.time() 7 print('index run time:%s'%(end - start)) 8 return get_time 9 @outter # index = outter(index) 10 def index(): 11 time.sleep(3) 12 print('今天的鸡哥又是格外的帅气!') 13 @outter #joke = outter(joke) 14 def joke(name): 15 time.sleep(1) 16 print('今天的%s只能做衬托...'%name) 17 18 index() 19 joke('tank')

使用方法:@+函数名

认证装饰器:

要求:执行函数index之前必须先输入用户名和密码 正确之后才能执行index

否则提示用户输入错误 结束程序

 1 def login(func):
 2     def inner(*args,**kwargs):
 3         username = input('please input your name>>>')
 4         password = input('please input your password>>>')
 5         if username == 'zzj' and password == '123456':
 6             func(*args,**kwargs)
 7         else:
 8             print('username or password error!')
 9     return inner
10 
11 @login
12 def index(name):
13     print('%s is a good gay'%name)
14     return 666
15 
16 index('jason')

 

 

 

原文地址:https://www.cnblogs.com/spencerzhu/p/11177972.html