1.闭包(Closure)的概念:

内部函数中对enclosing作用域的变量进行引用

 1 passline = 60
2 def func(val):
3 print('%x' % id(val))
4 if val >= passline:
5 print('pass')
6 else:
7 print('faild')
8
9 def in_func():
10 print(val)
11
12 in_func()
13 return in_func
14
15 f = func(80)
16 f() #in_func
17 print(f.__closure__)

运行结果:

5d4ff910
pass
80
80
(<cell at 0x000001B37C8B6CD8: int object at 0x000000005D4FF910>,)

按照正常的理解,当执行完func函数后,in_func函数无法使用func函数作用域内的变量val,但是通过上面的代码,可以看到val添加到了in_func的__closure__属性中(in_func的属性__closure__对val变量进行了引用,func执行完成后val没有被释放掉),

也就是说,在函数闭包中,内部函数中对enclosing作用域的变量进行引用,并将引用变量添加到了内部函数__closure__属性中

2.装饰器

所谓装饰器,是用来装饰函数,并且返回一个函数对象

如以下求和与求平均值的两个方法:

def my_sum(*args):
if len(args) == 0:
return 0
for item in args:
if not isinstance(item, int):
return 0
return sum(args) def my_average(*args):
if len(arg) == 0:
return 0
for item in args:
if not isinstance(item, int):
return 0
return sum(args) / len(args) print(my_sum(1,2,3))
print(my_average(2,3,4,'1'))

其中,两个方法中都有相同的一段的容错处理代码:

if len(arg) == 0:
return 0
for item in arg:
if not isinstance(item, int):
return 0

遵循程序设计的DRY原则,这段代码应该进行封装处理,这时便可引入函数闭包

def dec(func):
def in_func(*args):
if len(args) == 0:
return 0
for item in args:
if not isinstance(item, int):
return 0
return func(*args)
return in_func def my_sum(*args):
return sum(args) def my_average(*args):
return sum(args) / len(args) my_sum=dec(my_sum)
my_average=dec(my_average) print(my_sum(1,2,3))
print(my_average(2,3,4,''))

这样就对重复的代码进行了封装。而装饰器是一种语法糖,简化了代码的编写

def dec(func):
print('dec called')
def in_func(*args):
if len(args) == 0:
return 0
for item in args:
if not isinstance(item, int):
return 0
return func(*args)
return in_func @dec
def my_sum(*args):
print('my_sum called')
return sum(args)
@dec
def my_average(*args):
print('my_average called')
return sum(args) / len(args) # my_sum=dec(my_sum)
# my_average=dec(my_average) print(my_sum(1,2,3))
print(my_average(2,3,4,''))

运行结果:

dec called
dec called
my_sum called
6
程序执行到@dec时,调用 dec方法,返回in_dec,my_sum方法重新被赋值my_sum=in_dec(被装饰函数指向新的函数)
所以,装饰器@dec的作用就如同执行这行代码:
my_sum=dec(my_sum)

Python中闭包、装饰器的概念的更多相关文章

  1. 简单说明Python中的装饰器的用法

    简单说明Python中的装饰器的用法 这篇文章主要简单说明了Python中的装饰器的用法,装饰器在Python的进阶学习中非常重要,示例代码基于Python2.x,需要的朋友可以参考下   装饰器对与 ...

  2. 【Python】python中的装饰器——@

    对装饰器本来就一知半解的,今天终于弄清楚了,Python中的装饰器是对装饰者模式的很好运用,简化到骨子里了. python中为什么需要装饰器,看这里:http://www.cnblogs.com/hu ...

  3. Python 中实现装饰器时使用 @functools.wraps 的理由

    Python 中使用装饰器对在运行期对函数进行一些外部功能的扩展.但是在使用过程中,由于装饰器的加入导致解释器认为函数本身发生了改变,在某些情况下——比如测试时——会导致一些问题.Python 通过  ...

  4. 写python中的装饰器

    python中的装饰器主要用于在已有函数实现功能前附加需要输出的信息,下面将用实例展示我如何写装饰器. 首先分别尝试写装饰器装饰一个无参函数和一个有参函数(被装饰函数仅输出,无返回值情况下) def ...

  5. python中的装饰器decorator

    python中的装饰器 装饰器是为了解决以下描述的问题而产生的方法 我们在已有的函数代码的基础上,想要动态的为这个函数增加功能而又不改变原函数的代码 例如有三个函数: def f1(x): retur ...

  6. python中@property装饰器的使用

    目录 python中@property装饰器的使用 1.引出问题 2.初步改善 3.使用@property 4.解析@property 5.总结 python中@property装饰器的使用 1.引出 ...

  7. 理解Python中的装饰器

    文章先由stackoverflow上面的一个问题引起吧,如果使用如下的代码: @makebold @makeitalic def say(): return "Hello" 打印出 ...

  8. 理解Python中的装饰器//这篇文章将python的装饰器来龙去脉说的很清楚,故转过来存档

    转自:http://www.cnblogs.com/rollenholt/archive/2012/05/02/2479833.html 这篇文章将python的装饰器来龙去脉说的很清楚,故转过来存档 ...

  9. 【Python】 闭包&装饰器

    python中的函数本身就是对象,所以可以作为参数拿来传递.同时其允许函数的层级嵌套定义,使得灵活性大大增加. 闭包 闭包的定义:将函数的语句块与其运行所需要的环境打包到一起,得到的就是闭包对象.比如 ...

  10. python函数闭包-装饰器-03

    可调用对象 callable()  # 可调用的(这个东西加括号可以执行特定的功能,类和函数) 可调用对象即  callable(对象)  返回为  True  的对象 x = 1 print(cal ...

随机推荐

  1. java算法 蓝桥杯 高精度加法

    问题描述 在C/C++语言中,整型所能表示的范围一般为-231到231(大约21亿),即使long long型,一般也只能表示到-263到263.要想计算更加规模的数,就要用软件来扩展了,比如用数组或 ...

  2. 如何用CSS快速布局(一)—— 布局元素详细

    要快速进行网页排版布局,则必须对布局的元素有清晰的了解,才不会总是在细节处出错.这一篇先详解有关布局的因素作为布局基础:块级元素and内联元素.盒模型.准确定位.元素对齐.样式继承.下一篇则重点描述快 ...

  3. KB奇遇记(6):搞笑的ERP项目团队

    早在我们来之前,KB公司这边就已经组建了ERP项目组了,当时IT就只有一个人,属网管出身.而关键用户分两种类型:专职关键用户和兼职关键用户.专职关键用户组织结构上已经调动到信息部,常驻在项目组里工作, ...

  4. 深圳尚学堂:JavaScript的常见面试题

    经常说编程是一门技术专业,在找工作时面试官肯定不止看你的面试能力,还要看你的专业知识掌握,他可能会让你做一个小的编程测试,或者说考察你的语法知识掌握,今天,总结了一些关于在JavaScript中常常会 ...

  5. C++编程练习(10)----“图的最小生成树“(Prim算法、Kruskal算法)

    1.Prim 算法 以某顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树. 2.Kruskal 算法 直接寻找最小权值的边来构建最小生成树. 比较: Kruskal 算法主要是针对边来展开,边数 ...

  6. css3 3d学习心得

    css3 3d学习心得 卡片反转 魔方 banner图 首先我们要学习好css3 3d一定要有一定的立体感 通过这个图片应该清楚的了解到了x轴 y轴 z轴是什么概念了. 首先先给大家看一个小例子: 卡 ...

  7. php中 0 与 字符串比较的问题

    今天我的技术群里,被一个很不起眼的问题炸出很多基础不稳的phper,就是这么一句 : <?php if(0 == 'yes'){ echo 'yes'; }else{ echo 'no'; } ...

  8. 怎样在chrome中内置扩展,以及一些简单的定制

    本文中chromium 版本为54 参考资料: chromium如何新增extension API以及添加内部扩展 http://slides.com/luyuan/grit#/ 一.嵌入扩展 1.  ...

  9. 简学Python第三章__函数式编程、递归、内置函数

    #cnblogs_post_body h2 { background: linear-gradient(to bottom, #18c0ff 0%,#0c7eff 100%); color: #fff ...

  10. PhpCms_V9笔记

     一.建立虚拟站点 1.先更改www目录下的站点名称,再找到apache, 打开"Apache2\conf\extra"下的"httpd-vhosts.conf" ...