Python学习(十)—— 装饰器和函数闭包

装饰器

装饰器:本质就是函数,功能是为其他函数添加附加功能

原则:

1、不修改被修饰函数的源代码

2、不修改被修饰函数的调用方式

统计程序运行的时间(不使用装饰器):

  这种方法修改了源代码,不能用于已经上线的程序

 1 import time
 2 def calc(l):
 3     res = 0
 4     start_time = time.time()
 5     for i in l:
 6         res += i
 7         time.sleep(0.01)
 8     stop_time = time.time()
 9     print(stop_time - start_time)
10     return res
11
12 y = calc([1,2,3,4,5,6,7,8,9,10])
13 print(y)
14 # 0.1087961196899414
15 # 55

  这种方法修改了调用方式

 1 import time
 2 def timmer(func):
 3     start_time = time.time()
 4     y = func()
 5     stop_time = time.time()
 6     print(stop_time - start_time,"\n",y)
 7     return timmer
 8
 9 def calc():
10     res = 0
11     for i in range(1,11):
12         res += i
13         time.sleep(0.01)
14     return res
15
16 timmer(calc)
17
18 # 0.10875916481018066
19 #  55

统计程序运行的时间(使用装饰器):

 1 import time
 2 def timmer(func):
 3     def wrapper(*args,**kwargs):
 4         start_time = time.time()
 5         res = func(*args,**kwargs)
 6         stop_time = time.time()
 7         print(stop_time - start_time)
 8         return res
 9     return wrapper
10 @timmer
11 def calc(l):
12     res = 0
13     for i in l:
14         res += i
15         time.sleep(0.01)
16     return res
17
18 y = calc([1,2,3,4,5,6,7,8,9,10])
19 print(y)
20 # 0.10654282569885254
21 # 55

装饰器 = 高阶函数 + 函数嵌套 + 闭包

高阶函数

高阶函数的定义:满足下列任一条即可

1、函数接收的参数是一个函数名

2、函数的返回值是一个函数名

函数嵌套

在函数内部嵌套另一个函数

闭包

装饰器的框架

 1 import time
 2 def timmer(func): #参数是函数
 3     def wrapper(): #函数的嵌套
 4         start_time= time.time()
 5         # print(func)
 6         func() #函数闭包所以可以调用func
 7         end_time = time.time()
 8         print("running time is %s"%( end_time-start_time))
 9     return wrapper #返回是函数
10 @timmer  #装饰器名,相当于test = timmer(test),置于被修饰函数之前
11 def test():
12     time.sleep(3)
13
14 test()
15 # running time is 3.000131368637085

有参数的情况下框架:

 1 import time
 2 def timmer(func): #参数是函数
 3     def wrapper(*args,**kwargs): #函数的嵌套
 4         s_time = time.time()
 5         func(*args,**kwargs) #函数闭包所以可以调用func
 6         e_time = time.time()
 7         print("running time :" ,e_time-s_time)
 8     return wrapper #返回是函数
 9 @timmer
10 def test(name,gender,age):
11     time.sleep(3)
12     print(name)
13     print(gender)
14     print(age)
15
16 test("ally","female",20)
17 # ally
18 # female
19 # 20
20 # running time : 3.000988245010376

例子

  给主页加登录装饰器(出现重复登录情况)

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 def login(func):
 4     def wragger(*args, **kwargs):
 5         x = input("请输入用户名:")
 6         y = int(input("请输入密码:"))
 7         if x == "admin" and y == 123456:
 8             print("登录成功")
 9             res = func(*args, **kwargs)
10             return res
11         else:
12             pass
13
14     return wragger
15
16
17 @login
18 def index():
19     print("欢迎来到京东")
20
21
22 @login
23 def home():
24     print("欢迎回家")
25
26
27 @login
28 def shopping_car():
29     print("我的购物车")
30
31
32 @login
33 def order():
34     print("我的订单")
35
36
37 index()
38 # 请输入用户名:admin
39 # 请输入密码:123456
40 # 登录成功
41 # 欢迎来到京东

  给主页加登录装饰器的例子(不需重复登录)

 1 user_dic ={"user_name":None,"login":False}
 2 def auth_login(func):
 3     def wragger(*args, **kwargs):
 4         if user_dic["user_name"] and user_dic["login"]:
 5             res = func(*args, **kwargs)
 6             return res
 7         else:
 8             user_name = input("请输入用户名:")
 9             password = int(input("请输入密码:"))
10             if user_name == "admin" and password == 123456:
11                 user_dic["user_name"] = user_name
12                 user_dic["login"] = True
13                 print("登录成功")
14                 res = func(*args, **kwargs)
15                 return res
16     return wragger
17
18
19 @auth_login
20 def index():
21     print("欢迎来到京东")
22
23
24 @auth_login
25 def home():
26     print("欢迎回家")
27
28
29 @auth_login
30 def shopping_car():
31     print("我的购物车")
32
33
34 @auth_login
35 def order():
36     print("我的订单")
37
38 index()
39 shopping_car()
40 order()
41
42 # 请输入用户名:admin
43 # 请输入密码:123456
44 # 登录成功
45 # 欢迎来到京东
46 # 我的购物车
47 # 我的订单

  公司有多个用户

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 user_list = [
 4     {"user_name": "alex", "password": "123"},
 5     {"user_name": "admin", "password": "123456"},
 6 ]
 7 user_login = {"user_name": None, "login": False}
 8
 9 def auth_login(func):
10     def wragger(*args, **kwargs):
11         if user_login["user_name"] and user_login["login"]:
12             res = func(*args, **kwargs)
13             return res
14         else:
15             user_name = input("请输入用户名:").strip()
16             password = input("请输入密码:").strip()
17             for user_dic in user_list:
18                 if user_name == user_dic["user_name"] and password == user_dic["password"]:
19                     user_login["user_name"] = user_name
20                     user_login["login"] = True
21                     print("登录成功")
22                     res = func(*args, **kwargs)
23                     return res
24             else:
25                 print("用户或密码错误")
26     return wragger
27
28 @auth_login
29 def index():
30     print("欢迎来到京东")
31
32 @auth_login
33 def home():
34     print("欢迎回家")
35
36 @auth_login
37 def shopping_car():
38     print("我的购物车")
39
40 @auth_login
41 def order():
42     print("我的订单")
43
44 index()
45 shopping_car()
46 order()
47
48 # 请输入用户名:admin
49 # 请输入密码:123456
50 # 登录成功
51 # 欢迎来到京东
52 # 我的购物车
53 # 我的订单

函数闭包带参数装饰器

解压序列

交换值

1 f1 = 1
2 f2 = 2
3 f1,f2 = f2,f1
4 print(f1,f2)
5 # 2 1

一条语句多变量赋值,必须一一对应

 1 a,b,c = "hel"
 2 print("a:",a,"\nb:",b,"\nc:",c)
 3 # a: h
 4 # b: e
 5 # c: l
 6 x,y,z = 1,3,5
 7 print("x:",x,"\ny:",y,"\nz:",z)
 8 # x: 1
 9 # y: 3
10 # z: 5
11 u,v = [1,2],[4,5]
12 print(u,v)
13 # [1, 2] [4, 5]

如果只想取出特定值,可以不用索引

1 l = [0,1,2,3,4,5,6,7,8,9]
2 a,*_,b = l #实际上,可以使用*+任何字母或符号
3 print(a)
4 print(b)
5 # 0
6 # 9

原文地址:https://www.cnblogs.com/jennifer224/p/12399008.html

时间: 2024-10-06 07:51:33

Python学习(十)—— 装饰器和函数闭包的相关文章

六、PYTHON 学习之装饰器使用

Python是一种强大的语言,即可浅尝辄止,也可深入挖掘.很适合做科学计算.数据挖掘等等.今天我将简单介绍一下Python的装饰器(Decorators)的用法 . 假设我们想要庆祝下生日,需要邀请一些朋友过来参加.但是你有个讨厌的朋友,叫Joe,必须不能让他来啊.可能首先你想到的是建一个list,然后迭代查找并移除所有的Joe童鞋.这当然是个好方法,但是这里为了介绍装饰器,我们会用@来完成这个工作.虽然可能看起来没有什么必要,但是有助于大家学习装饰器的用法. 首先创建一个Python文件app

十、PYTHON 学习之装饰器加深理解

在第六章已经有所介绍,这里看到一篇比较好的文章转过来. 基本概念 装饰器是23z种设计模式之一,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理, Web权限校验, Cache等. 很有名的例子来理解,咖啡,加糖的咖啡,加牛奶的咖啡. 本质上,还是咖啡,只是在原有的东西上,做了"装饰",使之附加一些功能或特性. 例如记录日志,需要对某些函数进行记录 笨的办法,每个函数加入代码,如果代码变了,就悲催了 装饰器的办法,定义一个专门日志记录的装饰器,对需要的函数进行装饰.

python学习笔记--装饰器

1.首先是一个很无聊的函数,实现了两个数的加法运算: def f(x,y): print x+y f(2,3) 输出结果也ok 5 2.可是这时候我们感觉输出结果太单一了点,想让代码的输出多一点看起来不这么单调: def showInfo(fun): def wrap(x,y): print "The function before" func(x,y) print "The function after" return wrap def f(x,y): print

python学习-42 装饰器 --- 函数闭包1

函数闭包举例: def father(name): print('hello world') def son(): print('儿子说:我的爸爸是%s' % name) def grandfson(): print('孙子说:我的爷爷是%s' % name) grandfson() son() father('小明') 运行结果: hello world 儿子说:我的爸爸是小明 孙子说:我的爷爷是小明 Process finished with exit code 0 函数的包: 就是嵌套里的

python学习-43 装饰器 -- 函数闭包2

函数闭包为函数加上认证功能 1.登陆账号 user_dic ={'username':None,'login':False} def auth_func(func): def wrapper(*args,**kwargs): if user_dic['username'] and user_dic['login']: res = func(*args,**kwargs) return res username = input('账号:').strip() passwd = input('密码:'

Python学习之装饰器

装饰器出现的原因是因为我们应对新的需求:在不改变原函数调用方式的情况下,在这个函数前后加上扩展功能:它的本质是闭包函数. 装饰器的结构: def timmer(func): def inner(*args,**kwargs): '''添加函数调用之前的扩展代码''' ret = func(*args,**kwargs) '''添加函数调用之后的扩展代码''' return ret return inner 两个def 两个return互相对应. 装饰器的设计模式:是开放封闭原则:既对扩展是开放的

Python 学习笔记 - 装饰器

这一节了解了一些装饰器的简单使用. 首先来看一个预备知识,把一个函数当做参数,传入另外一个函数 比如说我传递outer(f1),我传入的是f1的内存地址,a=func()其实执行了f1()这个函数,并把返回值赋给了a,因此当我打印print(a),他会输出hee >>> def outer(func):     print(func)     a=func()     print(a) def f1():     print("aaa")     return &qu

Python学习之装饰器进阶

函数知识回顾: 函数的参数分为:实参和形参. 实参:调用函数的时候传入的参数: 形参:分为3种(位置参数.默认参数.动态传参) 位置参数:必须传值 def aaa(a,b): print(a,b) aaa(1,2) 默认参数:不是必须传参数 def bbb(x=10): print(x) # bbb() #x = 10 # bbb(20) #x = 20 动态传参 def ccc(*args):#1,2,3,4,5 print(args) ccc(1,2,3,4,5)#按位置传参数 t = (1

python学习之-装饰器

1. 什么是装饰器 装饰器就是用来为被装饰的对象新增功能的工具/函数,被装饰的对象可以是任意可调用的对象,装饰器本身也可以是任意可调用的对象 2. 为何要用装饰器 开放封闭原则:对修改封闭,对扩展开放 装饰器需要遵循的原则: 1. 不能修改被装饰对象的源代码 2. 不能修改被装饰对象的调用方式 PS:装饰器的目标:就是要在遵循原则1和2的前提下,为被装饰对象新增功能 3. 如何实现装饰器 import time def index():  #这是被装饰对象 time.sleep(1) print