闭包

1.作用域L_E_G_B(局部、内嵌、全局...):

 x=10#全局

 def f():
a=5 #嵌套作用域
def inner():
count = 7 #局部变量
print a
return 1

从内往外寻找 a 。

2.高阶函数

a.函数名可以作为参数输入

b.函数名可以作为返回值

3.闭包

 def outer():
x=10
def inner(): #条件1 inner是内部函数
print(x) #条件2 外部环境的一个变量 return inner #结论: 内部函数inner就是一个闭包 outer()()#调用inner
#同上
f = outer()#获得inner
f()#调用执行inner #不能直接调用inner,因为inner为局部变量,全局无法调用

执行结果

10
10 Process finished with exit code 0

第10行,获得inner变量,第11行执行inner函数,而执行inner函数时(在外部执行),其中x变量既不属于inner函数内部变量,也不属于全局变量,按理应该报错却没报错,这种现象称为闭包。

定义:如果在一个内部函数里,对在外部作用域(但不是全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。

在内部函数里(inner函数中),对在外部作用域的变量(x)进行引用(print),那么内部函数(inner)就被认为是闭包。

装饰器

 import time

 def foo():
print("foo.....")
time.sleep(2) def bar():
print("bar.....")
time.sleep(3) def show_time(f): #函数名作参数
start = time.time()
f()
end = time.time()
print("spend %s" % (end - start)) show_time(bar)

函数名作参数,减少重复代码。

执行结果:

bar.....
spend 3.0022976398468018 Process finished with exit code 0

但是以上方法改变了调用方式,加上所需时间功能后,不是直接用foo,而是用show_time,这样对所有使用foo函数的代码都需修改,违背了封闭开放原则。

 import time

 def foo():
print("foo.....")
time.sleep(2) def bar():
print("bar.....")
time.sleep(3) def show_time(f): #函数名作参数 ,装饰器
def inner():
start = time.time()
f()
end = time.time()
print("spend %s" % (end - start))
return inner foo = show_time(foo)
foo()

show_time即为装饰器,inner函数为闭包,f函数名变量即为外部作用域变量。

执行结果:

foo.....
spend 2.00213360786438 Process finished with exit code 0

但是以上方法还需要自己赋值,不够简便、优雅。

优雅的写法:

 import time

 def show_time(f): #函数名作参数 ,装饰器
def inner():
start = time.time()
f()
end = time.time()
print("spend %s" % (end - start))
return inner @show_time # foo = show_time(foo), 给foo函数添加一个计算所需时间的功能
def foo():
print("foo.....")
time.sleep(2) #foo = show_time(foo)
foo()

11行,给foo函数添加一个计算所需时间的功能,@show_time,可理解为foo = show_time(foo)。

执行结果:

foo.....
spend 2.002133369445801 Process finished with exit code 0

被装饰函数参数(功能函数加参数):

 import time

 def show_time(f): #函数名作参数 ,装饰器
def inner(x, y):
start = time.time()
f(x, y)
end = time.time()
print("spend %s" % (end - start))
return inner @show_time # add = show_time(add), 给add函数添加一个计算所需时间的功能
def add(a, b):
print(a + b)
time.sleep(1) #foo = show_time(foo)
add(1, 2)

执行结果:

3
spend 1.0010321140289307 Process finished with exit code 0

不定长参数:

 import time

 def show_time(f): #函数名作参数 ,装饰器
def inner(*x, **y):
start = time.time()
f(*x, **y)
end = time.time()
print("spend %s" % (end - start))
return inner @show_time
def add(*a, **b): # a为元组
sums = 0
for i in a:
sums += i
print(sums)
time.sleep(1) add(1, 2, 5, 7, 9)#不定长参数

其中a为元组。

执行结果:

24
spend 1.0011086463928223 Process finished with exit code 0

装饰器参数:

 import time

 def logger(flag=''):#默认空

     def show_time(f):  # 函数名作参数 ,装饰器
def inner(*x, **y):
start = time.time()
f(*x, **y)
end = time.time()
print("spend %s" % (end - start))
if flag == 'true':
print('日志记录')
return inner
return show_time def show_time(f): #函数名作参数 ,装饰器
def inner(*x, **y):
start = time.time()
f(*x, **y)
end = time.time()
print("spend %s" % (end - start))
return inner @logger('true') # 相当于@show_time,不过有了一个flag变量,相当于闭包
def add(*a, **b): # a为元组
sums = 0
for i in a:
sums += i
print(sums)
time.sleep(1) add(1, 2, 5, 7, 9)#不定长参数 @logger()
def bar():
print("bar......")
time.sleep(3) bar()

装饰器加参数flag,决定是否输出日志,此时show_time为闭包。

执行结果:

24
spend 1.001152515411377
日志记录
bar......
spend 3.00311541557312

Python装饰器(函数)的更多相关文章

  1. python 装饰器函数基础知识

    1.装饰器的本质--一个闭包函数 2.装饰器的功能--在不改变原函数及其调用方式情况下对原函数功能进行拓展 3.带参数和返回值的装饰器 def timer(func): @wraps(func) #使 ...

  2. python基础篇_004_装饰器函数

    python装饰器函数 1.装饰器函数引导 功能:计算函数执行时长 import time """ 方式一: 函数首位添加时间,差值就是函数执行时间 缺点:每个函数都要加 ...

  3. Python 装饰器(Decorators) 超详细分类实例

        Python装饰器分类 Python 装饰器函数: 是指装饰器本身是函数风格的实现; 函数装饰器: 是指被装饰的目标对象是函数;(目标对象); 装饰器类 : 是指装饰器本身是类风格的实现; 类 ...

  4. python 装饰器修改调整函数参数

    简单记录一下利用python装饰器来调整函数的方法.现在有个需求:参数line范围为1-16,要求把9-16的范围转化为1-8,即9对应1,10对应2,...,16对应8. 下面是例子: def fo ...

  5. Python装饰器、内置函数之金兰契友

    装饰器:装饰器的实质就是一个闭包,而闭包又是嵌套函数的一种.所以也可以理解装饰器是一种特殊的函数.因为程序一般都遵守开放封闭原则,软件在设计初期不可能把所有情况都想到,所以一般软件都支持功能上的扩展, ...

  6. python装饰器1:函数装饰器详解

    装饰器1:函数装饰器 装饰器2:类装饰器 装饰器3:进阶 先混个眼熟 谁可以作为装饰器(可以将谁编写成装饰器): 函数 方法 实现了__call__的可调用类 装饰器可以去装饰谁(谁可以被装饰): 函 ...

  7. python基础(8)-装饰器函数&进阶

    从小例子进入装饰器 统计一个函数执行耗时 原始版本 import time # time模块有提供时间相关函数 def do_something(): print("do_something ...

  8. 万恶之源 - Python装饰器及内置函数

    装饰器 听名字应该知道这是一个装饰的东西,我们今天就来讲解一下装饰器,有的铁子们应该听说,有的没有听说过.没有关系我告诉你们这是一个很神奇的东西 这个有多神奇呢? 我们先来复习一下闭包 def fun ...

  9. python装饰器中@wraps作用--修复被装饰后的函数名等属性的改变

    Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变),为了不影响,Python的functools包中提供了一个叫wraps的de ...

  10. python学习——装饰器函数

    一.装饰器函数的作用是什么 答:装饰器函数是在不修改原函数及其调用方式的情况下对原函数功能进行扩展 对于搞python开发的人来说,函数占据了至关重要的地位.都说学好函数你就可以去找工作了,好了,假如 ...

随机推荐

  1. servlet中关于下载

    package com.huawei.response; import java.io.BufferedInputStream;import java.io.IOException;import ja ...

  2. 禁止ImageCapture自动启动

    [禁止ImageCapture自动启动] 打开ImageCapture,点开左下角菜单,把Connecting this iPhone opens:的内容改为以下选项即可.

  3. Ice_cream’s world II(最小树形图,加虚点)

    Ice_cream’s world II http://acm.hdu.edu.cn/showproblem.php?pid=2121 Time Limit: 3000/1000 MS (Java/O ...

  4. 31-字符串转为 url 格式的两种不同情况

    将此字符串转为 url 格式的: # 如果是转化对象用:data=urllib.parse.urlencode(values) # 如果是转化字符串:s=urllib.parse.quote(s)

  5. halcon的tuple算子功能总结

  6. 在Qt(C++)中使用QThread实现多线程

    1. 引言 多线程对于需要处理耗时任务的应用很有用,一方面响应用户操作.更新界面显示,另一方面在"后台"进行耗时操作,比如大量运算.复制大文件.网络传输等. 使用Qt框架开发应用程 ...

  7. android4.2 高用zing拍照后,返回其它页面操作时,主线程关掉或程序退出的问题解决

    产生错误的代码: @Override protected void onCreate(Bundle savedInstanceState) { StrictMode.setThreadPolicy(n ...

  8. Android 实现在Activity中操作刷新另外一个Activity数据列表

    做android项目中遇到这样一个问题:有两个acticity,一个显示好友列表,另外一个显示会话列表,现在问题是在会话界面增加一个添加好友功能,添加好友后要求实时的刷新好友列表. 想了想,找了两种方 ...

  9. SOCKET句柄泄露带来的内存灾难

    前些时候游戏莫名其妙出现大量内存泄露,我感到很诧异,当然一般情况下游戏的内存管理是极其严苛的,出现如此大量的内存泄露到底是怎么回事? 句柄滥用导致的内存泄露会多夸张呢,尤其SOCKET,在某些客户端系 ...

  10. [原创]解决IPCH关闭后可能引发的无法调试的BUG

    前几天清理硬盘,发现大量IPCH目录,文件特别巨大,看着头大,所以决定改为临时模式,同时VS2015和VS2013我都改了,设置如下: (关键字:IPCH目录,VS大文件) 当设置好之后不会出现烦人的 ...