Python高级特性之闭包与装饰器实例详解


Posted in Python onNovember 19, 2019

本文实例讲述了Python高级特性之闭包与装饰器。分享给大家供大家参考,具体如下:

闭包

1.函数参数:

(1)函数名存放的是函数的地址
(2)函数名()存放的是函数内的代码
(3)函数名只是函数代码空间的引用,当函数名赋值给一个对象的时候,就是引用传递

def func01():
  print("func01 is show")
test = func01
print(func01)
print(test)
test()

结果:

Python高级特性之闭包与装饰器实例详解

2.闭包:

(1)内层函数可以访问外层函数变量

(2)闭包就是一个嵌套定义的函数,在外层运行时才开始内层函数的定义,然后将内部函数的引用传递函数外的对象(闭包外层函数的返回值为内层函数名)

(3)内部函数和使用的外部函数提供的变量构成的整体称为闭包

def func_out(rate):
  def func_in(money):
    print(rate * money)
  return func_in
usa_money = func_out(0.7)
usa_money(100)
usa_money(200)

执行结果:

Python高级特性之闭包与装饰器实例详解

装饰器

装饰器就是在不改变函数的原有代码的前提下 给函数添加新的功能,装饰器一般是一个闭包。

1.装饰器:

# 在不改变函数的原有代码的前提下 给函数添加新的功能
def func_out(func):
  def func_in():
    print("验证")
    func()
  return func_in
@func_out
def login():
  print("登录")
# 有装饰器 装饰器下面正好是一个函数
# login = func_out(login)  重点
login()

如果@func_out装饰器下刚好是一个login函数,会执行:

login = func_out(login)

所以会直接执行func_out内的代码,func为原login,即指向原login函数的地址空间并且返回内层函数名,即:

login = func_out(login) = func_in

所以login()的执行结果为func_in(),即:

print('验证')
func() # func指原login函数的地址

就实现了不改变原函数的情况下给函数添加新功能

执行结果:

Python高级特性之闭包与装饰器实例详解

2.装饰有返回指函数:

def func_out(func):
  def func_in():
    # ret = func()
    #  def login():
    #    return 100
    return func()
  return func_in
@func_out
def login():
  return 100
# login() ==> func_in()
# func ==> 原始的login
f = login()
print(f)

3.装饰有参数函数:

def func_out(func):
  def func_in(a):
    func(a)
  return func_in
@func_out
def login(a):
  print(a)
# login() ==> func_in()
# func ==> 原始的login
login(10)

4.装饰器通用版:

def func_out(func):
  def func_in(*args,**kwargs):
    return func(*args,**kwargs)
  return func_in
@func_out
def login(*args,**kwargs):
  print(args)
  print(kwargs)
# login() ==> func_in()
# func ==> 原始的login
login(10,20,age = "17",name="123")

5.类装饰器:

class Foo(object):
  def __init__(self, func):
    self.func = func
  def __call__(self):
    print("验证")
    self.func()
@Foo
def login():
  print("登录")
# login = Foo(login)
login()

6.多装饰器:

def func_out01(func01):
  print("func_out01 is show")
  def func_in01():
    print("func_in01 is show")
    func01()
  return func_in01
def func_out02(func02):
  print("func_out02 is show")
  def func_in02():
    print("func_in02 is show")
    func02()
  return func_in02
@func_out02 # login = func_out02(login)
@func_out01 # login = func_out01(login)
def login():
  print("login is show")
login()

执行结果:

因为@闭包名下为函数时才会实现装饰器,所以func_out1会先装饰函数,func_out2会后装饰函数,所以外层函数先执行func_out1,后执行func_out2;因为func_out1先装饰函数,func_out2后装饰函数,所以func_out1装饰后,原函数为先输出func_in1内的语句,再输出原login,然后func_out2装饰后,执行顺序为先输出func_in2的语句,再输出装饰后的login函数,即:func_in2——func_in1——login。

Python高级特性之闭包与装饰器实例详解

7.给装饰器传递函数:

def route(参数):
  print(参数)
  def func_out(func):
    def func_in():
      func()
    return func_in
  return func_out
@route(参数)
def index():
  return "index is show"

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
Python random模块常用方法
Nov 03 Python
python实现定时同步本机与北京时间的方法
Mar 24 Python
CentOS 6.X系统下升级Python2.6到Python2.7 的方法
Oct 12 Python
CentOS中升级Python版本的方法详解
Jul 10 Python
python 统计数组中元素出现次数并进行排序的实例
Jul 02 Python
对Python中for复合语句的使用示例讲解
Nov 01 Python
Django中如何使用sass的方法步骤
Jul 09 Python
python如何实现数据的线性拟合
Jul 19 Python
Python中and和or如何使用
May 28 Python
Ubuntu16安装Python3.9的实现步骤
Dec 15 Python
python使用pygame创建精灵Sprite
Apr 06 Python
PyTorch中permute的使用方法
Apr 26 Python
Python高级编程之继承问题详解(super与mro)
Nov 19 #Python
Python3 Tkinkter + SQLite实现登录和注册界面
Nov 19 #Python
Python csv文件的读写操作实例详解
Nov 19 #Python
Python高级property属性用法实例分析
Nov 19 #Python
wxPython之wx.DC绘制形状
Nov 19 #Python
python matplotlib拟合直线的实现
Nov 19 #Python
Python线程指南分享
Nov 19 #Python
You might like
国内咖啡文化
2021/03/03 咖啡文化
ThinkPHP采用GET方式获取中文参数查询无结果的解决方法
2014/06/26 PHP
浅谈Coreseek、Sphinx-for-chinaese、Sphinx+Scws的区别
2016/12/15 PHP
解决php extension 加载顺序问题
2019/08/16 PHP
PHP的图像处理实例小结【文字水印、图片水印、压缩图像等】
2019/12/20 PHP
禁用页面部分JavaScript方法的具体实现
2013/07/31 Javascript
Javascript学习笔记之函数篇(四):arguments 对象
2014/11/23 Javascript
JS交换变量的方法
2015/01/21 Javascript
使用mouse事件实现简单的鼠标经过特效
2015/01/30 Javascript
分析了一下JQuery中的extend方法实现原理
2015/02/27 Javascript
JS动画效果打开、关闭层的实现方法
2015/05/09 Javascript
javascript表单处理具体实现代码(表单、链接、按钮)
2016/05/07 Javascript
JS检测移动端横竖屏的代码
2016/05/30 Javascript
ES5 ES6中Array对象去除重复项的方法总结
2017/04/27 Javascript
深入浅出webpack之externals的使用
2017/12/04 Javascript
vue项目部署上线遇到的问题及解决方法
2018/06/10 Javascript
Nuxt.js SSR与权限验证的实现
2018/11/21 Javascript
JavaScript函数式编程(Functional Programming)纯函数用法分析
2019/05/22 Javascript
彻底搞懂并解决vue-cli4中图片显示的问题实现
2020/08/31 Javascript
nodejs中的异步编程知识点详解
2021/01/17 NodeJs
[00:56]2014DOTA2国际邀请赛 DK、iG 赛前探访
2014/07/10 DOTA
[58:00]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant BO3 第二场 2月7日
2021/03/11 DOTA
Python压缩解压缩zip文件及破解zip文件密码的方法
2015/11/04 Python
Django添加sitemap的方法示例
2018/08/06 Python
基于python框架Scrapy爬取自己的博客内容过程详解
2019/08/05 Python
tensorflow 报错unitialized value的解决方法
2020/02/06 Python
python 解压、复制、删除 文件的实例代码
2020/02/26 Python
详解CSS3:overflow属性
2020/11/17 HTML / CSS
英国汽车和货车租赁网站:Hertz英国
2016/09/02 全球购物
Juicy Couture Beauty官方网站:香水和化妆品
2019/03/12 全球购物
广州品高软件.net笔面试题目
2012/04/18 面试题
动物科学专业毕业生的自我评价
2013/11/29 职场文书
老人再婚离婚协议书范本
2014/10/27 职场文书
OpenCV-Python实现轮廓拟合
2021/06/08 Python
利用For循环遍历Python字典的三种方法实例
2022/03/25 Python
ubuntu20.04虚拟机无法上网的问题及解决
2022/12/24 Servers