函数之闭包函数和装饰器

。_饼干妹妹 提交于 2019-12-04 06:48:06

 

闭包函数和装饰器

一、闭包函数

1.什么是闭包函数?

字面意思:闭:封闭,包:包裹;闭包函数就是函数嵌套,函数对象,名称空间与作用域的结合体

  • 闭包函数必须在函数内部定义

  • 闭包函数可以引用外层函数的名字

2.闭包函数怎么用

闭包函数是为了装饰器做准备

def outer(num2):    num2 = 100    def inner():      # inner就是闭包函数        print(num2)   # 如果局部找不到变量名,再从全局找    return inner      # 返回inner​func = outer("num2")   # 本质是将inner函数名(函数地址)赋值给funcfunc()    # 调用inner函数
举例:# 直接传值​import requests​​# 调用爬虫包def spider_func(url):    response = requests.get(url)    # 接受网址的返回值    if response.status_code == 200:        # 判断http的状态码是不是200        print(len(response.text))        # print(response.text)​​url = 'https://www.taobao.com/'spider_func(url)​# 通过闭包函数传值​import requests​​def spider_outer(url):    def spider_inner():        response = requests.get(url)        print(len(response.text))​    return spider_inner     ​​url = 'https://www.taobao.com/'​spider_func = spider_outer(url)    # 本质是spider_inner这个函数的函数地址​spider_func()

二、装饰器

1.什么是装饰器?

字面意思就是修饰的工具,就是一种具有添加新功能能力的函数

装饰器必须遵循"开放封闭原则"

开放:对函数功能的添加是开放的, 意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况

封闭:对函数功能的修改是封闭的, 意味着对象一旦设计完成,就可以独立完成其工作,而不要对其进行修改

2.为什么要使用装饰器?

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

3.怎么使用装饰器

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

注意:使用装饰器要注意两点

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

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

​def download_movie(name):    '''模拟电影下载'''    print(f"电影{name}开始下载...")    time.sleep(3)    print(f"电影{name}下载完成...")    return f'tank与{name}'​​# 添加统计时间的装饰器def time_out(func):    def time_inner(*args, **kwargs):  # 可以接受任何输入的值        start_time = time.time()  # 收集开始时间        res = func(*args, **kwargs)  # 接受源代码输入的任意值并收集返回值        end_time = time.time()  # 收集结束时间        print(f'总时间{end_time - start_time}')  # 计算时间并打印        return res​    return time_inner  # 返回到闭包函数​​download_movie = time_out(download_movie)     # 将download_movie赋值给funcdownload_movie('辛德勒的名单')

注意:

# 装饰器模版def warpper(func):        def warpper_inner(*args, **kwargs):  # 可以接收原函数传入的任意值                res = func(*args, **kwargs)    # 同样                return res    # 将原函数的返回时原封不动的返回去            return warpper_inner     # 调用闭包函数​​def func1():    pass​func1 = warpper(func1)func1()    # 本质运行的程序的是warpper_inner()

4.装饰器的语法糖(@)

装饰器的语法糖,是属于装饰器的。@: 装饰器的语法糖# 注意: 在使用装饰器语法糖时,装饰器必须定义在被装饰对象之上。
# 添加统计时间的装饰器def time_out(func):    def time_inner(*args, **kwargs):  # 可以接受任何输入的值        start_time = time.time()  # 收集开始时间        res = func(*args, **kwargs)  # 接受源代码输入的任意值并收集返回值        end_time = time.time()  # 收集结束时间        print(f'总时间{end_time - start_time}')  # 计算时间并打印        return res​    return time_inner  # 返回到闭包函数​​@time_out     # 调用语法糖,  注意装饰器在原函数之前​def download_movie(name):    '''模拟电影下载'''    print(f"电影{name}开始下载...")    time.sleep(3)    print(f"电影{name}下载完成...")    return f'tank与{name}'​download_movie('辛德勒的名单')    # 运行函数​

 

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!