fpython-笔记(五)装饰器、匿名函数
一、装饰器
装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能,比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里面每个函数都加一个功能,用来统计每个函数的运行时间是多少,找出来运行比较慢的函数,来优化代码,或者一个功能在调用之前必须登陆,就需要添加一个新的功能,来统计程序的运行时间,那这样的话,就得修改每个函数了,需要改代码,但是代码特别多,改完了公司倒闭了,这时候装饰器就能排上用场了,它可以不改变原有的函数,原来的函数和原来一模一样,什么都不需要改变,只需要在函数外部加上调用哪个装饰器就可以了。so,装饰器的作用就是不改变原来函数的调用方式,不改变原来函数的代码,给它增加了一个新功能。但是不改变函数,给它增加新功能,那是不可能的,装饰器只不过是偷偷改变了原来的函数而已,而原来的函数不知不觉。
说白了就是函数嵌套+高阶函数
作用:就是在不改变原有函数的调用方式,入参的情况下给函数添加新功能
偷偷摸摸的给函数加上新功能,但是不改变原来的函数
使用装饰器需要了解的知识:
*1 函数即变量,意思是在python中函数可以当一个变量来用,函数名就是一个变量,这个变量存的实际上是这个函数的内存地址,在调用的时候从函数名里面这个内存地址找到这个函数。()代表调用函数,如果只打印函数名的话实际上就是打印了一下内存地址。
def test():
print('nihao')
print(test) # 打印函数的内存地址
test() # 调用函数`<function test at 0x0000000002383E18>
*2 高阶和嵌套函数
之前的章节提过,实际上装饰器就是高阶函数和嵌套函数的结合体
下面我们写一个简单的装饰器,用来计算函数的运行时间。
import time
def bar():
time.sleep(3)
print('测试执行时间')
def test_time(func)
start_time = time.time()
func()
stop_time = time.time
print('函数的运行时间是%s'%(stop_time - start_time))
test_time(bar)
运行结果:
测试执行时间
函数的运行时间是3.000171661376953
但是这样的话,我们每次要调用test_time(bar),而不是直接调用bar(),所以就改变了函数的调用方式。
这时我们就想到了装饰器。如果不修改调用代码,也就是意味着调用bar(),需要和test_time(bar)一样的
效果,如果test_time(bar)并咩有直接产生调用函数的效果,而是返回一个函数的内存地址,那么将
test1(bar)的返回值赋值给bar,然后,调用bar()的代码完全不用修改!import time
def test_time(func):
def deco():
start_time = time.time()
func()
stop_time = time.time()
print('函数的运行时间是%s'%(stop_time - start_time))
return deco
def bar():
time.sleep(3)
bar = test_time(bar) #把deco的内存地址返回给 bar
bar()
运行结果:
in the bar
函数的运行时间是3.000171661376953
函数test_time 其实就是一个装饰器,它把真正的业务方法func包裹在函数里面,看起来就像是bar被test_time装饰了
如果我们想偷懒不适用赋值语句bar = test_time(bar) ,那么我们就可以用到装饰器的语法糖@,语法糖的意思就是一种语法的简写
,他可以使代码看起来更加简洁,上面的bar = test_time(bar) 和@test_time 然后调用bar()效果是一样的。
import time
def test_time(func):
def deco():
start_time = time.time()
func()
stop_time = time.time()
print('函数的运行时间是%s'%(stop_time - start_time))
return deco
@test_time
def bar():
time.sleep(3)
print('in the bar')
运行的结果和上面一样
这样我们就提高了程序的可重复利用性,当其他函数需要调用装饰器时,可以直接调用。装饰器在python使用非常方便,这得益于python的函数
能够像朋友同的对象一样作为参数传递给其他函数,可以赋值给其他变量,可以作为返回值,被定义在另一个函数内。
如果装饰的函数带有参数,因为你也不知道被装饰的函数会传什么参数,所以可以使用可变参数和关键字参数来接收所有的参数,代码如下:
def test_time(func):
def deco(*args,**kwargs):
start_time = time.time()
func(*args,**kwargs)
stop_time = time.time()
print('函数的运行时间%s'%(stop_time - start_time))
return deco
@test_time
def test2(name,age):
time.sleep(2)
print('in the test2',name,age)
test2('niuhanyang',18)
运行结果:
in the test2: niuniu 18
the func run time is 2.0001144409179688
下面再用装饰器写一个实例,判断用户是否登录,判断的逻辑是这样,运行程序,打印菜单,如果是选择后台管理和添加商品,
就判断用户是否登录,如果没有登陆的话,让用户登陆,如果是查看商品就不需要登陆。
import time,json
def read_file(filename):
with open(filename) as fr:
res = json.load(fr)
return res
login_name = None
def auth(func):
dec(*args,**kwargs):
global login_name
if login_name:
res = func(*args,**kwargs)
return res
else:
user_dic = read_file('users.json')
count = 0
while count <3:
username = input('请输入用户名:').strip()
password = input('请输入密码:').strip()
if username !='' and password ! ='':
if username in user_dic:
if user_dic[username]['password'] = passsword
login_name =username
res = func(*args,**kwargs)
return res
else:
print('密码不正确!!!')
count +=1
else:
print('用户名不存在!!!')
count +=1
else:
print('用户名和密码都不能为空')
cout+ =1
return dec
下面是事先写好的uses.json
{
"admin": {
"password": "123456",
"cart": [
"mac",
"iphone"
]
},
"duguanglong": {
"password": "123456",
"cart": []
}
}
匿名函数
如果这个函数只需要执行一次,那就定义一个匿名函数,匿名函数只能处理比较简单的处理逻辑,只能写简单的表达式,不能写循环判断,比如三元运算符。
匿名函数使用lambda关键字,比如说要定义一个函数,它的功能是要返回两个数字相加,那就可以使用lambda,代码如下:
s = lambda x,y:x+y #冒号前面的x,y是入参,冒号后面的是返回值
print(s(1,9)) #因为函数即变量,如果没有顶一个变量把lambda存起来的话,他就不在内存里,就没有办法执行,所以把它放到s这个变量里面
s(1,9)
运行结果:10
fpython-笔记(五)装饰器、匿名函数的更多相关文章
- python学习笔记(五):装饰器、生成器、内置函数、json
一.装饰器 装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能,比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里 ...
- 20.python笔记之装饰器
装饰器 装饰器是函数,只不过该函数可以具有特殊的含义,装饰器用来装饰函数或类,使用装饰器可以在函数执行前和执行后添加相应操作. 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插 ...
- python笔记 - day4-之装饰器
python笔记 - day4-之装饰器 需求: 给f1~f100增加个log: def outer(): #定义增加的log print("log") ...
- muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor
目录 muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor Connector 系统函数connect 处理非阻塞connect的步骤: Connetor时序图 Accep ...
- Python学习笔记012——装饰器
1 装饰器 1.1装饰器定义 在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator). 1.2 装饰器分类 装饰器:函数装饰器,类装饰器,函数的装饰器,类的装饰器 装饰器:函数装饰函 ...
- python学习笔记之装饰器、递归、算法(第四天)
参考老师的博客: 金角:http://www.cnblogs.com/alex3714/articles/5161349.html 银角:http://www.cnblogs.com/wupeiqi/ ...
- Day11 Python基础之装饰器(高级函数)(九)
在python中,装饰器.生成器和迭代器是特别重要的高级函数 https://www.cnblogs.com/yuanchenqi/articles/5830025.html 装饰器 1.如果说装 ...
- python:带参数的装饰器,函数的有用信息
一.带参数的装饰器,函数的有用信息 def func1(): '''此函数的功能是完成的登陆的功能 return: 返回值是登陆成功与否(true,false) ''' print(333) func ...
- 关于Python装饰器内层函数为什么要return目标函数的一些个人见解
https://blog.csdn.net/try_test_python/article/details/80802199 前几天在学装饰器的时候,关于装饰器内层函数调用目标函数时是否return目 ...
- diango中让装了装饰器的函数的名字不是inner,而是原来的名字
让装了装饰器的函数的名字不是inner,而是原来的名字 from functools import wraps def wrapper(func): @wraps(func) # 复制了原来函数的名字 ...
随机推荐
- Min-Max 容斥的证明
这里有 Min-Max 容斥的证明以及唯一一道博主做过的例题... 上个结论: \[Min\{S\}=\sum_{T\subseteq S,T\not=\varnothing}(-1)^{|T|-1} ...
- shopnc如何配置微信支付和支付宝支付
步骤一,支付宝账号申请 申请支付宝商家账号 ,填写好公司名称,资质,审核过了,然后填写下面这些参数 步骤二 微信支付申请 登陆微信公众平台-企业微信支付,得到商户号,再申请密钥 注意:支付宝加密方式 ...
- Prometheus快速入门
Prometheus是一个开源的,基于metrics(度量)的一个开源监控系统,它有一个简单而强大的数据模型和查询语言,让我们分析应用程序.Prometheus诞生于2012年主要是使用go语言编写的 ...
- 在java中读取文件中的内容
package shi; import java.io.*; public class wenjianIO { public static void main(String agrs[]){ File ...
- 要了解mysql原理,还是要心里有点B树才行
要了解数据库索引的底层原理,我们就得先了解一种叫树的数据结构,而树中很经典的一种数据结构就是二叉树!所以下面我们就从二叉树到平衡二叉树,再到B-树,最后到B+树来一步一步了解数据库索引底层的原理! ...
- 生成EXCEL文件是经常需要用到的功能,我们利用一些开源库可以很容易实现这个功能。
方法一:利用excellibrary,http://code.google.com/p/excellibrary/ excellibrary是国人写的开源组件,很容易使用,可惜貌似还不支持.xlsx( ...
- 32. Longest Valid Parentheses (JAVA)
Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...
- iOS特殊界面旋屏设置的方法之一
1.AppDelegate.h @property (assign, nonatomic) BOOL allowRotation; 2.AppDelegate.m #pragma mark - 自动旋 ...
- Centos安装PHP PS:LAMP环境时,为少出错误,先安装一下编译环境
下面安装PHP时数显很多问题,为了减少问题,直接安装先yum一下 yum -y install gcc pcre pcre-devel gcc-c++ autoconf libxml2 libxml2 ...
- 一、IIS搭建前端静态模板_资源加载问题
一.模板文件说明和效果展示 二.IIS配置模板 三.解决方案 把资源文件复制到html目录内与index.htm同级,因为我iis指定站点就是该目录.