Python装饰器(函数)
闭包
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装饰器(函数)的更多相关文章
- python 装饰器函数基础知识
1.装饰器的本质--一个闭包函数 2.装饰器的功能--在不改变原函数及其调用方式情况下对原函数功能进行拓展 3.带参数和返回值的装饰器 def timer(func): @wraps(func) #使 ...
- python基础篇_004_装饰器函数
python装饰器函数 1.装饰器函数引导 功能:计算函数执行时长 import time """ 方式一: 函数首位添加时间,差值就是函数执行时间 缺点:每个函数都要加 ...
- Python 装饰器(Decorators) 超详细分类实例
Python装饰器分类 Python 装饰器函数: 是指装饰器本身是函数风格的实现; 函数装饰器: 是指被装饰的目标对象是函数;(目标对象); 装饰器类 : 是指装饰器本身是类风格的实现; 类 ...
- python 装饰器修改调整函数参数
简单记录一下利用python装饰器来调整函数的方法.现在有个需求:参数line范围为1-16,要求把9-16的范围转化为1-8,即9对应1,10对应2,...,16对应8. 下面是例子: def fo ...
- Python装饰器、内置函数之金兰契友
装饰器:装饰器的实质就是一个闭包,而闭包又是嵌套函数的一种.所以也可以理解装饰器是一种特殊的函数.因为程序一般都遵守开放封闭原则,软件在设计初期不可能把所有情况都想到,所以一般软件都支持功能上的扩展, ...
- python装饰器1:函数装饰器详解
装饰器1:函数装饰器 装饰器2:类装饰器 装饰器3:进阶 先混个眼熟 谁可以作为装饰器(可以将谁编写成装饰器): 函数 方法 实现了__call__的可调用类 装饰器可以去装饰谁(谁可以被装饰): 函 ...
- python基础(8)-装饰器函数&进阶
从小例子进入装饰器 统计一个函数执行耗时 原始版本 import time # time模块有提供时间相关函数 def do_something(): print("do_something ...
- 万恶之源 - Python装饰器及内置函数
装饰器 听名字应该知道这是一个装饰的东西,我们今天就来讲解一下装饰器,有的铁子们应该听说,有的没有听说过.没有关系我告诉你们这是一个很神奇的东西 这个有多神奇呢? 我们先来复习一下闭包 def fun ...
- python装饰器中@wraps作用--修复被装饰后的函数名等属性的改变
Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变),为了不影响,Python的functools包中提供了一个叫wraps的de ...
- python学习——装饰器函数
一.装饰器函数的作用是什么 答:装饰器函数是在不修改原函数及其调用方式的情况下对原函数功能进行扩展 对于搞python开发的人来说,函数占据了至关重要的地位.都说学好函数你就可以去找工作了,好了,假如 ...
随机推荐
- Eclipse安装Freemarker Editor插件
在下面网址里下载freemarker-ide: http://sourceforge.net/projects/freemarker-ide/files/ 下载完成后后解压,由于该IDE里面的free ...
- tfrecord
制作自己的TFRecord数据集,读取,显示及代码详解 http://blog.csdn.net/miaomiaoyuan/article/details/56865361
- PLSQL优化基础和性能优化 (学习总结)
PLSQL优化基础和性能优化 (学习总结) 网上有一篇关于PLSQL优化的文章,不错,个人根据自己的经验再稍加整理和归纳,总结PLSQL优化和性能调优 适合有一定PLSQL基础,需要进一步提高的学友看 ...
- SuSE 网卡配置模板
heidsoft:/etc/sysconfig/network # cat ifcfg.template ## This is a template for a network interface c ...
- java代码实现网络远程开机
http://my.oschina.net/kingfire/blog/156764 概述 远程开机(Wake onLAN)是指通过网络实现对服务器或者pc启动运行,现在很多网卡都支持的这个功能. 其 ...
- Castle ActiveRecord学习(八)事务
代码: public void UpdateThemeInfo(int id) { //事务 using (TransactionScope ctran = new TransactionScope( ...
- CentOS7防火墙firewall相关操作
1.firewalld的基本使用 启动: systemctl start firewalld 查看状态: systemctl status firewalld 停止: systemctl disabl ...
- python 开发简单的聊天工具-乾颐堂
python 太强大了,以至于它什么都可以做,哈哈,开个玩笑.但是今天要讲的真的是一个非常神奇的应用. 使用python写一个聊天工具 其实大家平时用的QQ类似的聊天工具,也是使用socket进行聊天 ...
- gp sql
appendonly -- drop table if exists test_appendonly; -- create table test_appendonly with(appendonly= ...
- IP转换成域名
DNS就是域名解析系统,它可以将IP转换成域名,也可以将域名转换成IP 1. 安装DNS服务 开始—〉设置—〉控制面板—〉添加/删除程序—〉添加/删除Windows组件—〉“网络服务”—〉选择“域名服 ...