一、装饰器

装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能,比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里面每个函数都加一个功能,用来统计每个函数的运行时间是多少,找出来运行比较慢的函数,来优化代码,或者一个功能在调用之前必须登陆,就需要添加一个新的功能,来统计程序的运行时间,那这样的话,就得修改每个函数了,需要改代码,但是代码特别多,改完了公司倒闭了,这时候装饰器就能排上用场了,它可以不改变原有的函数,原来的函数和原来一模一样,什么都不需要改变,只需要在函数外部加上调用哪个装饰器就可以了。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-笔记(五)装饰器、匿名函数的更多相关文章

  1. python学习笔记(五):装饰器、生成器、内置函数、json

    一.装饰器 装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能,比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里 ...

  2. 20.python笔记之装饰器

    装饰器 装饰器是函数,只不过该函数可以具有特殊的含义,装饰器用来装饰函数或类,使用装饰器可以在函数执行前和执行后添加相应操作. 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插 ...

  3. python笔记 - day4-之装饰器

                 python笔记 - day4-之装饰器 需求: 给f1~f100增加个log: def outer(): #定义增加的log print("log") ...

  4. muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor

    目录 muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor Connector 系统函数connect 处理非阻塞connect的步骤: Connetor时序图 Accep ...

  5. Python学习笔记012——装饰器

    1 装饰器 1.1装饰器定义 在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator). 1.2 装饰器分类 装饰器:函数装饰器,类装饰器,函数的装饰器,类的装饰器 装饰器:函数装饰函 ...

  6. python学习笔记之装饰器、递归、算法(第四天)

    参考老师的博客: 金角:http://www.cnblogs.com/alex3714/articles/5161349.html 银角:http://www.cnblogs.com/wupeiqi/ ...

  7. Day11 Python基础之装饰器(高级函数)(九)

    在python中,装饰器.生成器和迭代器是特别重要的高级函数   https://www.cnblogs.com/yuanchenqi/articles/5830025.html 装饰器 1.如果说装 ...

  8. python:带参数的装饰器,函数的有用信息

    一.带参数的装饰器,函数的有用信息 def func1(): '''此函数的功能是完成的登陆的功能 return: 返回值是登陆成功与否(true,false) ''' print(333) func ...

  9. 关于Python装饰器内层函数为什么要return目标函数的一些个人见解

    https://blog.csdn.net/try_test_python/article/details/80802199 前几天在学装饰器的时候,关于装饰器内层函数调用目标函数时是否return目 ...

  10. diango中让装了装饰器的函数的名字不是inner,而是原来的名字

    让装了装饰器的函数的名字不是inner,而是原来的名字 from functools import wraps def wrapper(func): @wraps(func) # 复制了原来函数的名字 ...

随机推荐

  1. Neo4j源代码分析

    1.下载neo4j源码 https://github.com/neo4j/neo4j/ 参考文章 原文地址:https://blog.csdn.net/e15273/article/details/7 ...

  2. AVCaptureSession拍照,摄像,载图总结

    AVCaptureSession [IOS开发]拍照,摄像,载图总结 1 建立Session  2 添加 input  3 添加output  4 开始捕捉 5 为用户显示当前录制状态 6 捕捉 7 ...

  3. 已知链表头结点指针head,写一个函数把这个链表逆序

    Node* ReverseList ( Node *head ) { if ( head == NULL || head->next == NULL ) return head; Node *p ...

  4. rest_framework框架的分页

    class MyPageNumberPagination(PageNumberPagination): page_size = 1 page_query_param = 'page' page_siz ...

  5. CCPC-Wannafly Winter Camp Day1 (Div2, onsite) - I 起起落落

    题目描述 无聊的wlswls正在观察某个商品的价格,wlswls一共观察了nn天,每天这个商品都会有一个价格p_ipi​. 定义一个长度为2m+1(3\leq2m+1\leq n)2m+1(3≤2m+ ...

  6. At grand 022 GCD序列构造 dp/floyd二进制变换最少费用

    A diverse words指的是每一个字母在单词中出现的次数不超过1的单词 题目要求你求出字典序比当前给定单词大的字典序最小单词 1.如果给定的单词长度小于26 就遍历一次在单词尾部加上字典序最小 ...

  7. iptables常用语法与案例

    常用命令语法: [root@www ~]# iptables [-t tables] [-L] [-nv] 选项与参数: -t :后面接 table ,例如 nat 或 filter ,若省略此项目, ...

  8. React Autocomplete(自动完成输入)示例教程

    React Autocomplete示例教程是今天的主题.在现代Web开发中,使用React改善用户体验是很容易.自动完成的概念很简单.它是基于用户输入的建议列表.然后,用户可以按Enter键以完成短 ...

  9. 深入理解MySql事务

    事务是MySQL等关系型数据库区别于NoSQL的重要方面,是保证数据一致性的重要手段.本文将首先介绍MySQL事务相关的基础概念,然后介绍事务的ACID特性,并分析其实现原理. MySQL博大精深,文 ...

  10. python装饰器的简单理解

    如果你接触 Python 有一段时间了的话,想必你对 @ 符号一定不陌生了,没错 @ 符号就是装饰器的语法糖. 装饰器的使用方法很固定: 先定义一个装饰函数(帽子)(也可以用类.偏函数实现) 再定义你 ...