Python之闭包and装饰器
闭包和装饰器是Python中非常重要的一种语法格式,在日常工作中应用非常广泛。
首先,我先为大家简单的介绍一下闭包的概念。
闭包:闭包是在函数嵌套的基础上,内层函数使用到外层函数的变量,且外层函数返回内层函数的引用的一种语法格式。
闭包的基本格式,代码实现:
def outer():
num = 0
def inner():
# 使用外部函数的变量
print(num)
return inner # 返回inner函数在内存空间中的地址 # 将outer函数的返回值赋值给变量f,也就是说将f指向outer函数中的inner函数的内存地址
f = outer()
# 调用inner函数
f()
我们学习闭包的作用,其实就是为了学习装饰器。
那么,我们先来了解一下什么是装饰器。
装饰器就是通过闭包来对指定的函数进行功能的扩充,装饰器在函数定义时就会执行。
装饰器的特点:
1.不修改指定修饰函数的代码,
2.不修改指定修饰函数的调用方式,
3.给指定修饰函数增加相应的功能。
装饰器的种类:
1.普通装饰器
普通装饰器就是闭包语法格式的基础上,满足装饰器的特点的一种语法格式。
普通装饰器的代码实现:
def decorator(func):
# 此时func指向的是show函数
def inner(*args,**kwargs):
# 装饰的代码
ret = func()
return ret
return inner @decorator # 原理为 show = decorator(show)
# 此时show指向的是decorator函数中的inner函数
def show():
print('show run....') # 此时相当于调用decorator函数中的inner函数,并函数的返回值赋值给ret
ret = show()
图示如下:

1.1 多个装饰器装饰同一个函数:
多个装饰器装饰同一个函数的执行过程,先执行距离需要装饰函数近的装饰器,然后在执行距离需要装饰函数远的装饰器。
通过代码实现:
def make_div(func):
"""对被装饰的函数的返回值 div标签"""
# func指向是p中的inner函数的内存空间地址
def inner():
return "<div>" + func() + "</div>"
return inner def make_p(func):
"""对被装饰的函数的返回值 p标签"""
# func 指向的是content函数的内存空间地址
def inner():
return "<p>" + func() + "</p>"
return inner # 装饰过程: 1 content = make_p(content) 2 content = make_div(content)
# content = make_div(make_p(content))
# 当执行make_div的语法糖时,传递的是make_p中的inner函数的内存空间地址
@make_div
# make_div相当于装饰make_p修饰后的函数
@make_p # 按照顺序从下向上依次装饰,其根据是装饰器只能装饰已有函数# 当执行make_p的语法糖时,传递的是connet函数的内存空间地址
def content():
# content指向是p中的inner函数内存空间地址
return "人生苦短"
result = content()
print(result)
代码解读:
@make_div
@make_p
def show():
pass
执行流程:
1.@make_p装饰show函数
2.@make_div装饰@make_p修饰后的函数也就是make_p中的inner函数
2.类装饰器
类装饰器就是通过一个类来装饰函数,相较于普通装饰器,类装饰器可以使用父类中的方法。
类装饰器的代码实现:
class Decorator(object):
# 使用init方法来接收需要装饰的函数
def __init__(self, func):
# func指向show函数所在的内存空间地址
# 使用__func指向需要装饰的函数的内存空间地址
self.__func = func # 可以让类的对象通过对象名()的方式被调用
def __call__(self, *args, **kwargs):
# 此时相当于调用了show函数
ret = self.__func(*args, **kwargs)
return ret @Decorator # 原理是 show = Decorator(show)
# 此时show指向的是Decorator类的对象的内存地址
def show():
print('show run .....') # 此时表示Decorator对象被调用,并接受show函数的返回值
ret = show()
在以上代码中,类中的init方法就相当于闭包中的外层函数用来接收被装饰的函数,call方法就相当于闭包中内层函数用来编写装饰代码以及调用被装饰的函数。
图示如下:

3.带有参数的装饰器
带有参数的装饰器就是使用装饰器装饰函数的时候可以传入指定参数,语法格式: @装饰器(参数,...)
代码实现:
# 设置路由表,将字典当做路由表
router ={} def set_args(url):
# url 传递的参数
def set_func(func):
# func --> show方法的内存空间地址
def inner():
func()
# 将inner函数的内存空间地址添加到路由表中
# key = url
# value = inner函数的内存空间地址
router[url] = inner
# 返回inner函数的内存空间地址
return inner
# 返回set_func函数的内存空间地址
return set_func # 装饰器在函数定义时就会执行 # 1.先执行set_args('/show.html'),
# 相当于先调用set_args函数并进行参数的传递,
# 最后得到set_args的返回值也就是set_func
# 2.在执行@运算符,相当于执行装饰器@set_func
# @set_func --> show = set_func(show)
# 此时show ---> set_args.set_func.inner
@set_args('/show.html')
def show():
print('show run ....') def error():
print('error run....') def browser(url):
func = error
if url in router:
func = router[url]
# func()相当于调用了字典中符合条件的函数
func() if __name__ == '__main__':
browser('/show.html')
代码解读:
@set_args('/show.html')
def show():
pass
其中@set_args('/show.html'),按照运算符优先级应该先执行()也就是先执行set_atgs('/show.html'),然后再执行@运算符。
执行流程是:
1.先执行set_args('/show.html'),相当于调用set_args()函数,并进行传参;
2.接受set_args()函数的返回值,并结合@运算数(@set_func),对show函数进行装饰。
重点代码的执行流程图解:

Python之闭包and装饰器的更多相关文章
- Python函数编程——闭包和装饰器
Python函数编程--闭包和装饰器 一.闭包 关于闭包,即函数定义和函数表达式位于另一个函数的函数体内(嵌套函数).而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量.参数.当其中一个 ...
- python之闭包与装饰器
python闭包与装饰器 闭包 在函数内部定义的函数包含对外部的作用域,而不是全局作用域名字的引用,这样的函数叫做闭包函数. 示例: #-------------------------------- ...
- 关于python的闭包与装饰器的实验
首先看闭包,在嵌套函数内添加返回值,可以通过外部函数读取内部函数信息 #encoding=utf-8 #闭包应用 #先定义闭包函数,并使用 def outer(func): def inner(): ...
- python中闭包和装饰器
前言: 编程语言发展的过程中,我们为了提高代码利用率,发明了函数式编程.函数将代码封装起来,我们需要用到此功能函数的时候,调用一下就可以了.但是使用的过程中,也遇到了一些问题,比如函数实现的功能不够, ...
- python的闭包与装饰器
原文发表在我的博客主页,转载请注明出处 前言 如果把python当作脚本语言,每次就是写个几十行上百行来处理数据的话,装饰器也许不是很必要,但是如果要开发一个大型系统,装饰器是躲不开的,最开始体会ry ...
- Python的闭包和装饰器
什么是闭包 python中函数名是一个特殊的变量,它可以作为另一个函数的返回值,而闭包就是一个函数返回另一个函数后,其内部的局部变量还被另一个函数引用. 闭包的作用就是让一个变量能够常驻内存. def ...
- Python高级--闭包与装饰器
前言:在Python中,闭包是一种非常有用的功能!它通常与装饰器一起搭配使用,可以在不改变被装饰函数的功能的基础上,完成更多的功能.如权限认证. 一.如何定义闭包 1.闭包就是两个嵌套的函数,外层函数 ...
- python中闭包和装饰器的理解(关于python中闭包和装饰器解释最好的文章)
转载:http://python.jobbole.com/81683/ 呵呵!作为一名教python的老师,我发现学生们基本上一开始很难搞定python的装饰器,也许因为装饰器确实很难懂.搞定装饰器需 ...
- Python作用域-->闭包函数-->装饰器
1.作用域: 在python中,作用域分为两种:全局作用域和局部作用域. 全局作用域是定义在文件级别的变量,函数名.而局部作用域,则是定义函数内部. 关于作用域,我要理解两点:a.在全局不能访问到局部 ...
随机推荐
- React中使用create-react-app创建项目,运行npm run eject建立灰度报错
我在运行npm run eject建立测试环境和正式环境时候报错 这里的问题是是脚手架添加.gitgnore文件,但是却没有本地仓库,按照以下顺序就可以正常使用 git add . git commi ...
- 2019-9-23:渗透测试,基础学习,http协议数据包的认识,html css的认识,笔记
Burp suite功能模块Dashboard:扫描Proxy:拦截包,代理 drop:放弃Intruder:爆破Decoder:编码,解码repeater:重放comparer:比较 BP,prox ...
- Airtest介绍与脚本入门
前言 通过阅读本小节教程,你将了解以下内容: 一个Airtest脚本例子的详细解析 如何在Python脚本中调用Airtest接口 图片语句的参数介绍 Airtest介绍 Airtest是一款基于Py ...
- Python模块——loguru日志模块简单学习
Python loguru模块简单学习 首先安装模块:pip install logoru,然后引入模块: from loguru import logger 1.直接输出到console logge ...
- TensorFlow2.0
安装开发环境 1.首先安装 anaconda(https://www.anaconda.com/) 2.修改anaconda的镜像源 conda config --add channels https ...
- 当url中出现汉字
- Linux常用基本命令 (逐步添加)
Linux jobs命令 fg , bg , jobs , & , ctrl + z都是跟系统任务有关 一.&命令 用在一个命令的最后,可以把这个命令放到后台执行 二.Ctrl + z ...
- 鲲鹏云实验-.NET Core 3.0-开始使用
[摘要] 介绍Ubuntu 18.04环境下.NET Core 3.0的安装配置.初始项目的生成和运行 1. 基础环境 2vCPUs | 4GB | kc1.large.2 Ubuntu 18.04 ...
- 洛谷 题解 P5534 【【XR-3】等差数列】
我又双叒叕被包菜辣! 题目 这道题是不久前的考试题,现在来水一篇题解 扯回正题 题目很明显的告诉你了,这是一个等差数列, 然后,还告诉你了首项, 第二项, 项数. 你还想咋滴 告诉了你首项和第二项,相 ...
- [TimLinux] Django 中间件
1. 定义 中间件是一个钩子框架,深入到django的请求/响应处理过程中.这是一个轻量.底层插件系统,目的是全局修改django的输入或输出.每一个中间件组件都是用来处理特定的功能.例如django ...