闭包

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. Java调用SQL Server的存储过程详解

    转载自Microsoft的官方文档 http://msdn2.microsoft.com/zh-cn/library/ms378995.aspx收录于 www.enjoyjava.net/f25 本文 ...

  2. 7.25 1figting!

    TEXT 97 Health consumerism 保护消费者健康权益 The wellness boom 健康产业飞速发展(陈继龙编译) Jan 4th 2007 | NEW YORK From ...

  3. linux 使用systemctl 启动服务报错: Error: No space left on device

    By default, Linux only allocates 8192 watches for inotify, which is ridiculously low. And when it ru ...

  4. FP昨天的新单,今天交期回写到2020年

    昨天新单6900000053,回写交期到2020年.在此视图查看此单回写的日期V_OUT_SHIPMENT_PLAN_TESTS,可看到日期是2020年. 1.检查OUT_SHIPMENT_PLAN表 ...

  5. 在Spring使用junit注解进行单元测试

    在Spring中可以使用junit配合注解进行单元测试 一.常用注解 1.@RunWith(SpringJUnit4ClassRunner.class),让测试运行于spring测试环境2.@Cont ...

  6. ROS launch启动文件的理解与编写

    博客参考:https://blog.csdn.net/weixin_41995979/article/details/81784987 和 https://www.cnblogs.com/zjiaxi ...

  7. springMVC框架介绍以及运行流程(图解)

    1 Springmvc是什么? spring web mvc和struts2都属于表现层的框架,spring web mvc是spring框架的一部分(所以spring mvc与spring之间不需要 ...

  8. Pwdump v7.1

    提取windows系统密码  和 hash值

  9. 这样的UX设计师简历,HR分分钟给你来电话

    BLS调查显示,软件开发和IT,用户体验设计,产品经理和项目管理这三个职位在未来有非凡的发展前景.其中,用户体验设计师是目前最有需求的创意产业工作之一.10年里就业增长率高达22.1%,工作岗位数3, ...

  10. 本周MySQL官方verified/open的bug列表(11月15日至11月21日)

    本周MySQL verified的bug列表(11月15日至11月21日) 1. Bug #70923    Replication failure on multi-statement INSERT ...