闭包

定义:内部函数对外部函数变量的引用,则将该函数与用到的变量称为闭包。

闭包必须满足以下三个条件:

  • 必须有一个内嵌函数。
  • 内嵌函数必须引用外部函数中的变量。
  • 外部函数返回值必须是内嵌函数的引用。
def func(num):
def func_in(m):
print num, m # 结果:10 3
new_num = num ** m
return new_num
return func_in if __name__ == '__main__':
ret = func(10)
res = ret(3)
print res # 结果:1000

说明:func_in指向func_in()函数,return func_in 将函数的引用返回,用ret接收了这个返回值,ret就指向了func_in所指向的函数体,即func_in()函数。最后调用执行ret所指的函数。这就是闭包的整个过程,func_in()函数以及该函数内用到的变量num就称为闭包。简单说就是如果一个内嵌函数访问了外部嵌套函数作用域内的变量,则这个内嵌函数和用到的变量就称为闭包。将内嵌函数的语句和这些语句的执行环境打包在一起后,得到的函数对象称为闭包。

装饰器

装饰器是闭包的一种使用场景,在定义装饰器时需要传入一个函数对象,在此函数执行之前或者之后都可以追加其它的操作。

装饰器本质上是一个返回函数的高阶函数,装饰器接收要增强的函数,然后在装饰器内部进行功能增强。让函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。

使用场景:性能测试,插入日志,事务管理,权限校验...。就好比是一个切面,也就是我们之后学习中会提到的叫面向切面编程(aop)。

开放封闭原则:开放表现在不改动源码(破坏原本业务逻辑)的同时扩展新的功能。封闭表现在不允许随意去修改源代码。

def outer(fun):
def inner():
print "功能开始前记录日志"
fun()
print "功能结束后记录日志"
return inner def work():
print "hello world" work = outer(work)
work() # 结果打印三行,分别是:功能开始前记录日志 hello world 功能结束后记录日志

无参无返回值的装饰器,示例如下

def outer(fun):
def inner():
print "功能开始前记录日志"
fun()
print "功能结束后记录日志"
return inner @outer # @outer 的效果等同于 work = outer(work),此时work变量指向inner()函数,work()即调用inner()函数。
def work():
print "hello world" work() # 结果打印三行,分别是:功能开始前记录日志 hello world 功能结束后记录日志

无参有返回值的装饰器,示例如下

def make_one(fun):
def wrapper():
return "===" + fun() + "==="
return wrapper def make_two(fun):
def inner():
return "---" + fun() + "---"
return inner @make_one
@make_two
def work():
return "hello world" print work() # 结果:===---hello world---===
# 首先执行装饰器make_two,即work = make_two(work)。这时work变量指向inner()函数。inner()函数里面的fun()函数指向work()函数。
# 然后执行装饰器make_one,即work = make_one(work)。这时work变量指向wrapper()函数。wrapper()函数里面的fun()函数指向inner()函数。
# 最后执行work()的时候,先执行wrapper()函数,运行里面的fun()函数时候,即执行inner()函数,返回"---hello world---"。

有参有返回值的装饰器,示例如下

def make_one(fun):
def wrapper(name, age, sex):
fun(name, age, sex)
return "有参有返回值的装饰器,返回值啦"
return wrapper @make_one
def work(name, age, sex):
print "我叫:%s,年龄:%s,性别:%s" % (name,age,sex) print work("小刘",27,"男")
# 运行结果:
# 我叫:小刘,年龄:27,性别:男
# 有参有返回值的装饰器,返回值啦

通用装饰器,示例如下

# 无参数的装饰器
def make_one(func):
def wrapper(*args, **kwargs):
print args, kwargs
return func(*args, **kwargs)
return wrapper @make_one
def work():
print "Hello world" work()
# 输出结果:
# () {}
# Hello world
# 有参数的装饰器
def make_one(func):
def wrapper(*args, **kwargs):
print args, kwargs
return func(*args, **kwargs)
return wrapper @make_one
def work(name, age, sex):
print "我叫:%s,年龄:%s,性别:%s" % (name,age,sex) work("小刘", 27, "男")
# 输出结果:
# ('\xe5\xb0\x8f\xe5\x88\x98', 27, '\xe7\x94\xb7') {}
# 我叫:小刘,年龄:27,性别:男
# 有参数有返回值的装饰器
def make_one(func):
def wrapper(*args, **kwargs):
print args, kwargs
res = func(*args, **kwargs)
return res # work函数的返回值
return wrapper @make_one
def work(name, age, sex):
return "我叫:%s,年龄:%s,性别:%s" % (name,age,sex) res = work("小刘", 27, "男") # 这里work变量指向wrapper()函数,func变量指向被装饰的真正的work()函数。
print res
# 运行结果:
# ('\xe5\xb0\x8f\xe5\x88\x98', 27, '\xe7\x94\xb7') {}
# 我叫:小刘,年龄:27,性别:男

附加:当我们定义一个函数的时候,其实也可以理解为我们定义了一个函数变量,我们可以将其作为值赋值给一个变量,或者当作一个方法参数传递。Python中函数也是一个对象,并且可以被直接赋值给变量,就可以通过该变量调用该函数。

参考:https://www.toutiao.com/i6700739314055119367/?tt_from=weixin&utm_campaign=client_share&wxshare_count=1&timestamp=1570675241&app=news_article&utm_source=weixin&utm_medium=toutiao_android&req_id=201910101040410100140470382201FC1A&group_id=6700739314055119367

Python—闭包和装饰器的更多相关文章

  1. python 闭包和装饰器

    python 闭包和装饰器 一.闭包闭包:外部函数FunOut()里面包含一个内部函数FunIn(),并且外部函数返回内部函数的对象FunIn,内部函数存在对外部函数的变量的引用.那么这个内部函数Fu ...

  2. python闭包与装饰器

    转自小马哥: 闭包和装饰器充分体现了Python语法糖的优雅感觉. 在本文中,我们的实验要完成两个工作,一个是加法,一个是累计调用加法的次数,最普通的Python程序可以这么写: def valida ...

  3. 高逼格利器之Python闭包与装饰器

    生活在魔都的小明,终于攒够了首付,在魔都郊区买了一套房子:有一天,小明踩了狗屎,中了一注彩票,得到了20w,小明很是欢喜,于是想干脆用这20万来装修房子吧(decoration): 整个装修过程,小明 ...

  4. Python 简明教程 --- 22,Python 闭包与装饰器

    微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 当你选择了一种语言,意味着你还选择了一组技术.一个社区. 目录 本节我们来介绍闭包与装饰器. 闭包与 ...

  5. Python闭包及装饰器

    Python闭包 先看一个例子: def outer(x): def inner(y): return x+y return innder add = outer(8) print add(6) 我们 ...

  6. python闭包以及装饰器

    通俗的定义:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure).它只不过是个“内层”的函数,由一个名字(变量)来指代,而这个名字(变 ...

  7. python闭包和装饰器

    本文目录: 1. 闭包的解析和用法 2. 函数式装饰器 3. 类装饰器 一.闭包 闭包是一种函数,从形式上来说是函数内部定义(嵌套)函数,实现函数的扩展.在开发过程中,考虑到兼容性和耦合度问题,如果想 ...

  8. python闭包和装饰器(转)

    一.python闭包 1.内嵌函数 >>> def func1(): ... print ('func1 running...') ... def func2(): ... prin ...

  9. 详解Python闭包,装饰器及类装饰器

    在项目开发中,总会遇到在原代码的基础上添加额外的功能模块,原有的代码也许是很久以前所写,为了添加新功能的代码块,您一般还得重新熟悉源代码,稍微搞清楚一点它的逻辑,这无疑是一件特别头疼的事情.今天我们介 ...

随机推荐

  1. Easy User Manager System writeup

    0x01 解题 思路 一个进程用自己的ip去申请拿到code然后进入verify页面,另外一个进程去申请8.8.8.8 步骤 1. 首先注册一个账号 然后用两个不同的浏览器进入Change页面.这里我 ...

  2. 简单的LNMP安全加固

    安全加固 Nginx安全加固: Nginx配置文件 (nginx.conf):/usr/local/nginx/nginx.conf 禁用autoindex: autoindex:是Nginx的目录浏 ...

  3. 「SAP技术」SAP HU上面的'Obj.to Which HU Belongs'栏位初探

    SAP HU上面的'Obj.to Which HU Belongs'栏位初探 HU02,创建一个新的HU, 保存之, HU03显示这个HU 189141203942, 其'obj.to Which H ...

  4. HashMap与HashTable的区别和理解

    Hashmap的理解 1:HashMap是基于哈希表的Map接口的非同步实现.此实现提供所有可选的映射操作,并允许使用null值和null键.HashMap储存的是键值对,HashMap很快.此类不保 ...

  5. iOpenWorskSDK下载和答疑贴

    1 iOpenWorksSDK对VS2013-VS2017的支持插件 https://files.cnblogs.com/files/baihmpgy/iOpenWorksSDK.vsix.zip 2 ...

  6. CSharpGL(55)我是这样理解PBR的

    CSharpGL(55)我是这样理解PBR的 简介 PBR(Physically Based Rendering),基于物理的渲染,据说是目前最先进的实时渲染方法.它比Blinn-Phong方法的真实 ...

  7. H5混合应用之上下文切换

    一.native/web/hybrid 简介 目前主流应用程序大体分为:Native App(原生应用).Web App(网页应用).Hybrid App(混合应用),它们三者的优缺点比较如下表: 应 ...

  8. Linux war包部署jenkins

    一.介绍Jenkins 1.Jenkins概念 Jenkins是一个功能强大的应用程序,允许持续集成和持续交付项目,无论用的是什么平台.这是一个免费的源代码,可以处理任何类型的构建或持续集成.集成Je ...

  9. 【UOJ#242】【UR#16】破坏蛋糕(计算几何)

    [UOJ#242][UR#16]破坏蛋糕(计算几何) 题面 UOJ 题解 为了方便,我们假定最后一条直线是从上往下穿过来的,比如说把它当成坐标系的\(y\)轴. 于是我们可以处理出所有交点,然后把它们 ...

  10. HikariCP监控指标介绍和应用

    概述 HikariCP提供了一些监控指标,他的监控指标都是基于MicroMeter提供出来的,然后支持Prometheus和Dropwizard.本次我们将讨论一下HikariCp的监控指标有哪些,为 ...