1 2 3 4

闭包函数和装饰器

闭包函数和装饰器

一-什么是闭包函数?

	闭:封闭

​ 包:包裹

​ 比如手机的举例

​ 1.闭包函数必须在函数内部定义

​ 2.闭包函数可以引用外层函数的名字

​ -闭包函数是:函数的嵌套、函数的对象、名称空间和作用域 结合体。

​ ****闭合函数是为了装饰器做准备

def func(y):
    x = 100
    #inner 是一个闭包函数
    def inner():
        print(x)
        print(y)
    return inner
inner = func(1)
inner()
>>>>>>
100
1

二、装饰器

​ -什么是装饰器?

​ 装饰:装饰 ,修饰。

​ 器:工具

​ ***开放封闭 装饰器必须遵循“开放封闭“的原则

​ -开放:

​ 对函数的功能添加是开放的;

​ -封闭:

​ 对函数的功能修改是封闭的。

​ -装饰器的作用?

​ -在不修改被装饰对象的源代码和调用方式前提下,添加新的功能。

​ ##装饰器的定义必须遵顼:

​ -不修改被装饰对象的源代码

​ -不修改被装饰对象的调用方式

​ -为什么要使用装饰器?

​ 可以解决代码冗余问题,提高代码的可扩展性

​ -怎么使用装饰器?

​ -装饰器的应用:

​ -登录时间

​ -登录认证

​ -编写装饰器

​ 通过闭包函数来实现装饰器

#爬虫的获取技术
import requests # 爬虫请求工具,外国大佬给我们提供的爬虫的第三方请求库
#方式一直接传参
def spider_func(url):  #往url发送请求,获取相响应数据
    response =  requests.get(url)  #必须接受url
    if response.status_code ==200:
        #状态码:200
        print(len(response.text)) #获取当前的url中所有文本
        print(response.text)
url = 'https://fanyi.baidu.com/#en/zh/spider'
spider_func(url)
>>>>>>>>>
219724    ###len
<!DOCTYPE html> ####文本
<html>
<head>

用闭包函数的方法
def wrapper(url):
    def spider_func():
        response = requests.get(url)
        if response.status_code == 200:
            print(len(response.text))
            print(response.text)
    return spider_func  #return 的位置一定要特别注意
url ='https://fanyi.baidu.com/#en/zh/spider'
spider_baidu = wrapper(url)
spider_baidu()
>>>>>>>>
# 功能: 统计下载电影的函数的运行时间
import time
def downlode_moive():
    print('开始下载电影......')  #模拟下载电影
    time.sleep(5)#等待3秒钟
    print('电影下载成功......')#电影下载成功
    return '千与千寻.mp4'

start_time = time.time()  #获取当前时间戳
downlode_moive()
end_time = time.time()#获取当前时间戳
print(f'下载消耗的时间{end_time - start_time}')

# 功能: 统计下载电影的函数的运行时间
import time
def download_movie():
    print('开始下载电影......')  #模拟下载电影
    time.sleep(2)#等待3秒钟
    print('电影下载成功......')#电影下载成功
    return '千与千寻.mp4'
#
# start_time = time.time()  #获取当前时间戳
# download_movie()
# # end_time = time.time()#获取当前时间戳
# print(f'下载消耗的时间{end_time - start_time}')

def download_record(func):
    def inner_movie():
        start_time = time.time()
        res = func()
        end_time = time.time()
        print(f'消耗时间:{end_time - start_time}')
        return res
    return inner_movie

download_movie = download_record(download_movie)####调用函数有个先后的顺序,download_moive---》inner时候 调用了inner函数,执行download——moive ,最下面的还没有轮到执行
download_movie()
>>>>>>>
开始下载电影......
电影下载成功......
消耗时间:2.00022292137146
    
 #####被接收对象接收2个参数   
import time
def download_movie(a,c):
    print(f'{a,c}电影开始下载......')
    time.sleep(2)
    print('电影下载完成......')
    return '太阳.mp4'

def download_record(func):
    def inner_movie(a,c):
        # url = 'https://www.cnblogs.com/wangeraaa/p/10236180.html'
        start_time = time.time()
        res = func(a,c)
        end_time = time.time()
        print(f'下载时间:{end_time - start_time}')
        print(res)

    return inner_movie
download_movie = download_record(download_movie)
download_movie('avd',c = 'dfe')
>>>>>>>>
('avd', 'dfe')电影开始下载......
电影下载完成......
下载时间:2.000197410583496
太阳.mp4

####被装饰的对象接收多个参数
import time
def download_movie(*arg,**kwargs):
    print(f'{*arg,kwargs}电影开始下载......')
    time.sleep(2)
    print('电影下载完成......')
    return '太阳.mp4'

def download_record(func):
    def inner_movie(*arg, **kwargs ):
        # url = 'https://www.cnblogs.com/wangeraaa/p/10236180.html'
        start_time = time.time()
        res = func(*arg,**kwargs)
        end_time = time.time()
        print(f'下载时间:{end_time - start_time}')
        print(res)

    return inner_movie
download_movie = download_record(download_movie)
download_movie('avd','dfe',url = 'https://www.cnblogs.com/wangeraaa/p/10236180.html')
>>>>>>>>
C:\Users\86187\AppData\Local\Programs\Python\Python36\python.exe E:/PycharmProjects/study/11.8.py
('avd', 'dfe', {'url': 'https://www.cnblogs.com/wangeraaa/p/10236180.html'})电影开始下载......
电影下载完成......
下载时间:2.001342296600342
太阳.mp4

装饰器的完整最终模板

def func1():#####被装饰的对象
    pass

def wrapper(func):
    def inner(*arg, **kwargs):
        #让用户输入内容
        username = input('请输入你的名字:')
        if username == 'tank':
            print('right')
            res = func(*arg, **kwargs)
            return res
        else:
            print('wrong')
    return inner

func1 = wrapper(func1)
func1()

语法糖

'''
装饰器的语法糖,是属于装饰器的。 语法糖是python内置的,可以引用所有的装饰器
@: 装饰器的语法糖

# 注意: 在使用装饰器语法糖时,装饰器必须定义在被装饰对象之上。
'''
import time


# 统计函数执行时间装饰器
def wrapper(func):  # 被装饰对象
    def inner(*args, **kwargs):  # 被装饰对象的参数
        # 调用前增加新功能
        start_time = time.time()
        # 调用被装饰对象,并接收返回值
        res = func(*args, **kwargs)

        # 调用后添加新功能
        end_time = time.time()
        print(end_time - start_time)

        return res
    return inner


# func函数需要执行3秒

# 无参装饰器
# 使用装饰器
@wrapper  # wrapper(func)  ---> func
def func():

    time.sleep(3)
    
func()


# # 不用装饰器
# def func2():
#     time.sleep(3)
#
# func()
举例如下
import time
def download_record(func):
    def inner_movie(a,c):
        # url = 'https://www.cnblogs.com/wangeraaa/p/10236180.html'
        start_time = time.time()
        res = func(a,c)
        end_time = time.time()
        print(f'下载时间:{end_time - start_time}')
        print(res)

    return inner_movie
# download_movie = download_record(download_movie)
# download_movie('avd',c = 'dfe')
@download_record
def download_movie(a,c):
    print(f'{a,c}电影开始下载......')
    time.sleep(2)
    print('电影下载完成......')
    return '太阳.mp4'

download_movie('ss','fff')
>>>>>>>>>>
('ss', 'fff')电影开始下载......
电影下载完成......
下载时间:2.0004498958587646
太阳.mp4

posted @ 2019-11-12 18:44  ^更上一层楼$  阅读(105)  评论(0编辑  收藏  举报