python闭包和装饰器(转)

一、python闭包

1、内嵌函数

>>> def func1():
...     print (‘func1 running...‘)
...     def func2():
...             print (‘func2 running...‘)
...     func2()
...
>>> func1()
func1 running...
func2 running...

内部函数func2作用域都在外部函数func1作用域之内 
如果试图在外部函数的外部调用内部函数将会报错

>>> func2()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name ‘func2‘ is not defined

如果试图在一个内部函数里对外部作用域(不包括外部函数的外部作用域)的变量进行引用,内部函数就会被认为是闭包

>>> def FuncX(x):
...     def FuncY(y):
...             return x*y
...     return FuncY

对于FuncY函数来说,对在FuncX函数的整个作用域(FuncY函数的非全局作用域的外部作用)的变量x进行引用,自此就可以说FuncY函数就是所谓的闭包

>>> f = FuncX(8)
>>> f
<function FuncY at 0x7f3a436fc2a8>
>>> type(f)
<type ‘function‘>
>>> f(10)
80
>>> FuncX(7)(8)
56

由于闭包本身是基于内部函数这一概念而来,所以不能在外部函数的外部作用域对内部函数进行调用

>>> FuncY(8)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name ‘FuncY‘ is not defined

既然是基于内部函数这一概念而来,自然对于内部函数来说对引用外部函数作用域内的变量进行修改,将会启动解释器的屏蔽机制

>>> def Func1():
...     x = 233
...     def Func2():
...             x *=x
...             return x
...     return Func2()
...
>>> Func1()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in Func1
  File "<stdin>", line 4, in Func2
UnboundLocalError: local variable ‘x‘ referenced before assignment

x*=x的左值此时是内部函数作用域里的变量,此时试图将没有定义的数据进行平方操作,因此报错

>>> def Func1():
...     x = 233
...     def Func2():
...             x = 321
...             return x
...     return Func2()
...
>>> Func1()
321

内部函数创建x变量并且屏蔽外部函数作用域内的x变量

python3之前的解决办法

应用容器类型(list,tuple之类的)存放外部函数作用域的变量从而不会被屏蔽机制屏蔽掉,因为容器类型不是存放在栈里面

>>> def Func1():
...     x = [233]
...     def Func2():
...             x[0] *= x[0]
...             return x[0]
...     return Func2()
...
>>> Func1()
54289

python3之后的解决办法:nonlocal关键字

>>> def Func1():
...     x = 233
...     def Func2():
...     nonlocal x
...             x *= x
...             return x
...     return Func2()
...
>>> Func1()
54289

二、装饰器

事实上,装饰器就是一种的闭包的应用,只不过其传递的是函数:

@makeitalic 装饰器将函数 hello 传递给函数 makeitalic,函数 makeitalic 执行完毕后返回被包装后的 hello 函数,而这个过程其实就是通过闭包实现的。@makebold 也是如此,只不过其传递的是 @makeitalic 装饰过的 hello 函数,因此最后的执行结果 <b> 在 <i>外层,这个功能如果不用装饰器,其实就是显式的使用闭包:

闭包的作用

闭包的最大特点是可以将父函数的变量与内部函数绑定,并返回绑定变量后的函数(也即闭包),此时即便生成闭包的环境(父函数)已经释放,闭包仍然存在,这个过程很像类(父函数)生成实例(闭包),不同的是父函数只在调用时执行,执行完毕后其环境就会释放,而类则在文件执行时创建,一般程序执行完毕后作用域才释放,因此对一些需要重用的功能且不足以定义为类的行为,使用闭包会比使用类占用更少的资源,且更轻巧灵活,现举一例:假设我们仅仅想打印出各类动物的叫声,分别以类和闭包来实现:

可以看到输出结果是完全一样的,但显然类的实现相对繁琐,且这里只是想输出一下动物的叫声,定义一个 Animal 类未免小题大做,而且 voice 函数在执行完毕后,其作用域就已经释放,但 Animal 类及其实例 dog 的相应属性却一直贮存在内存中:

而这种占用对于实现该功能后,则是没有必要的。

除此之外,闭包还有很多其他功能,比如用于封装等,另外,闭包有效的减少了函数参数的数目,这对并行计算非常有价值,比如可以让每台电脑负责一个函数,然后串起来,实现流水化的作业等。

转自:http://blog.csdn.net/ChangerJJLee/article/details/52598629

https://segmentfault.com/a/1190000004461404

时间: 2024-10-07 23:42:01

python闭包和装饰器(转)的相关文章

Python闭包和装饰器

(1)python的LEGB: LEGB是指:按照L>E>G>B 的顺序优先级进行变量查找. L:local函数内部作用域,是最底层的单个函数里面: E:enclosing函数内部与内嵌函数之间,是有内部函数的函数里面: G:global 全局作用域,是一个.py文件中: B:build-in内置作用域,比如:tuple,list,元组.是所有.py文件中. (2)闭包 闭包是指:一个函数中内嵌了另一个函数,这个内嵌的函数会使用外部函数的参数变量,作为判决内嵌函数的不同运行模式的参考.最

python闭包以及装饰器

闭包 简单理解 所谓闭包简单点说就是定义一个函数,这个函数里面还有一个函数,此时里面的函数和外面函数中的变量之间就产生了闭包关系. 代码理解 # 定义一个函数 def test(num): # 里面还有一个函数 def test_inner(num_inner): # 这个函数和外面函数的变量num之间就产生了闭包 print(num + num_inner) return test_inner fun = test(10) fun(10) fun(20) 以上代码执行的结果是:20和30 从执

python闭包及装饰器

一.闭包 1.闭包就是在函数内部定义函数并返回内部函数 2.闭包实现代码的封装和复用 3.实例如图所示,内部定义一个比较函数,给定边界值即做出不同的判断 . 二.装饰器 1.装饰器就是利用闭包的原理 [email protected]就是装饰器的语法糖 3.装饰器可以给函数添加功能 4.实例如图所示,给求和函数添加参数预处理的功能

python闭包、装饰器

内部函数 闭包: 闭包将内部函数自己的代码和作用域以及外部函数的作用结合起来. 闭包的词法变量不属于全局名字空间域或者局部的--而是属于其他的名字空间,带着流浪的作用域. 闭包对于安装计算,隐藏状态,以及在函数对象和作用域中随意的切换是很有用的. 闭包也是函数,但是他们能携带一些额外的作用域. 实例 装饰器 装饰器是在函数调用之上的修饰 这些修饰是当声明一个函数或者方法的时候,才会应用的额外调用 使用装饰器的情形有: --引用日志 --增加计时逻辑来检测性能 --给函数加入事物的能力 装饰器实例

python闭包与装饰器

闭包闭包:两个函数的嵌套,外部函数返回内部函数的引用,外部函数一定有参数def 外部函数(参数): def 内部函数(): pass return 内部函数 他跟函数之间的区别: 1.格式两个函数嵌套 2.闭包外部函数的参数可以在内存中保持装饰器装饰器是什么:闭包加@xxx装饰器的作用:在不改变原先的函数值跟调用的方式,添加额外的功能装饰器的代码: def set_fun(func): def call_fun(*args,**kwargs): return func(*args,**kwarg

python闭包和装饰器的理解

闭包: 两个函数的嵌套,外部函数返回内部函数的引?,外部函数?定有参数 def 外部函数(参数): def 内部函数(): pass return 内部函数 他跟函数之间的区别: 1.格式两个函数嵌套 2.闭包外部函数的参数可以在内存中保持 装饰器是什么:闭包加@xxx 装饰器的作?:在不改变原先的函数值跟调?的?式,添加额外的功能 装饰器的代码: def set_fun(func): def call_fun(*args,**kwargs): return func(*args,**kwarg

python 闭包与装饰器

1.闭包--返回子函数名 作用:使用子函数之外的父函数的变量 闭包就是你调用了一个函数a,这个函数a反悔了一个子函数名b,这个返回的函数b就叫做闭包 代码举例 def a(): test = 'aa' def b(): print(test) return 1 return b c = a() print(c) print(c()) 统计做一件事情所需要的时间 做一批事情都想统计时间,如何做  装饰器=闭包+函数式编程 import time def deco(func): def _deco(

闭包和装饰器使用案例

''' @Author: 冯浩 @Date: 2019-12-04 22:58:49 @LastEditors: 冯浩 @LastEditTime: 2019-12-05 00:03:25 @FilePath: \bob_develop\python\闭包和装饰器.py ''' def deco(str_): def func0(func): print('func0', str_) def func1(num): print('func1', num) return func(num) ret

21.python中的闭包和装饰器

python中的闭包从表现形式上定义(解释)为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure). 以下说明主要针对 python2.7,其他版本可能存在差异. 也许直接看定义并不太能明白,下面我们先来看一下什么叫做内部函数: def wai_hanshu(canshu_1): def nei_hanshu(canshu_2): # 我在函数内部有定义了一个函数 return canshu_1*canshu_2 return