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程序中进行文件读取和写入操作的教程
Apr 28 Python
简单谈谈python中的Queue与多进程
Aug 25 Python
python 中random模块的常用方法总结
Jul 08 Python
Python数据类型中的“冒号“[::]——分片与步长操作示例
Jan 24 Python
Python3网络爬虫中的requests高级用法详解
Jun 18 Python
python发qq消息轰炸虐狗好友思路详解(完整代码)
Feb 15 Python
宝塔面板成功部署Django项目流程(图文)
Jun 22 Python
使用keras实现非线性回归(两种加激活函数的方式)
Jul 05 Python
Pycharm 2020.1 版配置优化的详细教程
Aug 07 Python
浅谈python 类方法/静态方法
Sep 18 Python
python 基于wx实现音乐播放
Nov 24 Python
Python中生成ndarray实例讲解
Feb 22 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
php横向重复区域显示二法
2008/09/25 PHP
fsockopen pfsockopen函数被禁用,SMTP发送邮件不正常的解决方法
2015/09/20 PHP
标准版Eclipse搭建PHP环境的详细步骤
2015/11/18 PHP
非常实用的php验证码类
2016/05/15 PHP
PHPMailer使用QQ邮箱实现邮件发送功能
2017/08/18 PHP
PHPMailer ThinkPHP实现自动发送邮件功能
2018/06/10 PHP
JQuery读取XML文件数据并显示的实现代码
2009/12/16 Javascript
js confirm()方法的使用方法实例
2013/07/13 Javascript
javascript函数式编程实例分析
2015/04/25 Javascript
使用CamanJS在Web页面上处理图像的技巧
2015/08/18 Javascript
JavaScript通过HTML的class来获取HTML元素的方法总结
2016/05/24 Javascript
浅谈javascript运算符——条件,逗号,赋值,()和void运算符
2016/07/15 Javascript
如何提高Dom访问速度
2017/01/05 Javascript
Dropify.js图片宽高自适应的方法
2017/11/27 Javascript
JS Object.preventExtensions(),Object.seal()与Object.freeze()用法实例分析
2018/08/25 Javascript
在vue项目中引入高德地图及其UI组件的方法
2018/09/04 Javascript
Vue 幸运大转盘实现思路详解
2019/05/06 Javascript
一篇文章带你从零快速上手Rollup
2020/09/07 Javascript
js数组的基本使用总结
2021/01/18 Javascript
[42:36]DOTA2上海特级锦标赛B组败者赛 VG VS Spirit第二局
2016/02/26 DOTA
python实现电子词典
2020/04/23 Python
python数据结构之二叉树的建立实例
2014/04/29 Python
tensorflow训练中出现nan问题的解决
2018/02/10 Python
python print 按逗号或空格分隔的方法
2018/05/02 Python
Python中函数的返回值示例浅析
2019/08/28 Python
用python进行视频剪辑
2020/11/02 Python
python中子类与父类的关系基础知识点
2021/02/02 Python
全球领先的鞋类零售商:The Walking Company
2016/07/21 全球购物
美国乡村商店:Plow & Hearth
2016/09/12 全球购物
PUMA官方商城:世界领先的运动品牌之一
2016/11/16 全球购物
文员个人求职自荐信
2013/09/21 职场文书
工业设计专业推荐信
2013/10/29 职场文书
农村产权制度改革实施方案
2014/03/21 职场文书
十佳好少年事迹材料
2014/08/21 职场文书
会计试用期自我评价怎么写
2014/09/18 职场文书
八项规定个人对照检查材料思想汇报
2014/09/25 职场文书