Python开发-day20-函数

生成器

生成器总结

 

 

 

 

 

 

 1 # -*- coding:utf-8 -*-
 2 # @Time:2022/4/1 8:58
 3 # @Author:Henry Scofield
 4 # @File:2.py
 5 # @Software:PyCharm
 6 
 7 age = 10
 8 res = True if age > 10 else False
 9 List = ['a' for i in range(10)]
10 g_List = ('a' for i in range(10))  # 生成器表达式
11 
12 
13 def test():
14     for i in range(4):
15         yield i
16 
17 
18 t = test() # t生成器对象
19 
20 for i in t:  # 如果这里遍历完了,下面list(t1)就是空列表了!
21     print(i)
22 
23 # print(t) # <generator object test at 0x0000016294349970>
24 t1 = (i for i in t)  # t1 生成器对象
25 # print(t1) # <generator object <genexpr> at 0x0000019A4A229A50>
26 print(list(t1))  # [0, 1, 2, 3]
View Code

 

 

 1 # -*- coding:utf-8 -*-
 2 # @Time:2022/4/1 8:58
 3 # @Author:Henry Scofield
 4 # @File:2.py
 5 # @Software:PyCharm
 6 
 7 age = 10
 8 res = True if age > 10 else False
 9 List = ['a' for i in range(10)]
10 g_List = ('a' for i in range(10))  # 生成器表达式
11 
12 
13 def test():
14     for i in range(4):
15         yield i
16 
17 
18 t = test()  # t生成器对象,要迭代才有值,迭代完就没值了
19 
20 t1 = (i for i in t)
21 t2 = (i for i in t)
22 print(list(t1))  # [0, 1, 2, 3] # 如果这里遍历完了,下面list(t1)就是空列表了!
23 print(list(t2))  # []
View Code

 

 

 

 

 

迭代器协议

 

 

 1 # -*- coding:utf-8 -*-
 2 # @Time:2022/4/1 8:39
 3 # @Author:Henry Scofield
 4 # @File:def函数.py
 5 # @Software:PyCharm
 6 def test():
 7     yield 1  # 相当于return 1
 8     yield 2
 9     # print("")
10 
11 
12 t = test()
13 
14 
15 def run():
16     print("from run")
17     print("from run")
18     print("from run")
19 
20 
21 run()
22 
23 
24 def test():
25     print("from run")
26     yield 1  # 相当于return 相当于保存状态,next()一次用一次
27     print("from run")
28     yield 2
29     # print("")
30 
31 
32 t = test()
33 
34 # 迭代器协议 可迭代对象
35 next(t)
36 
37 print("abcd")
38 print("abcd")
39 print("abcd")
40 print("abcd")
41 
42 next(t)
43 
44 # t.__next__() 从上次迭代后的位置开始迭代。 # StopIteration 已经走完了两个print,在迭代会报错
45 # t.send('123')# StopIteration 已经走完了两个print,在迭代会报错
View Code

装饰器

迭代器

 

 

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

原则:

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

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

 1 # -*- coding:utf-8 -*-
 2 # @Time:2022/4/1 9:21
 3 # @Author:Henry Scofield
 4 # @File:3.py
 5 # @Software:PyCharm
 6 import time
 7 
 8 
 9 # 被修饰函数上线后,不能随意再改源代码
10 def cal(l):
11     start_time = time.time()
12     res = 0  # 初始为0
13     for i in l:
14         time.sleep(0.1)
15         res += i  # 求和
16     stop_time = time.time()
17     print("函数的运行时间是 %s " % (stop_time - start_time))
18     return res
19 
20 
21 print(cal(range(100)))
22 
23 
24 def index():
25     pass
26 
27 
28 def home():
29     pass
30 
31 
32 index()  # index()调用就index()调用,不修改被修饰函数的调用方式
举例1
 1 # -*- coding:utf-8 -*-
 2 # @Time:2022/4/1 9:31
 3 # @Author:Henry Scofield
 4 # @File:4.py
 5 # @Software:PyCharm
 6 import time
 7 
 8 
 9 def timmer(func):
10     def wapper(*args, **kwargs):
11         start_time = time.time()
12         res = func(*args, **kwargs)
13         stop_time = time.time()
14         print("函数的运行时间是 %s " % (stop_time - start_time))
15         return res
16 
17     return wapper
18 
19 
20 @timmer
21 def cal(l):
22     res = 0  # 初始为0
23     for i in l:
24         time.sleep(0.1)
25         res += i  # 求和
26     return res
27 
28 
29 res = cal(range(20))
30 print(res)
举例2

 

装饰器的知识储备

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

 高阶函数

 1 # -*- coding:utf-8 -*-
 2 # @Time:2022/4/1 9:40
 3 # @Author:Henry Scofield
 4 # @File:5-高阶函数.py
 5 # @Software:PyCharm
 6 import time
 7 
 8 # def foo():
 9 #     time.sleep(3)
10 #     print("Hello!")
11 #
12 #
13 # def test(func):
14 #     print(func)
15 #     start_time = time.time()
16 #     func()  # 输出参数的值
17 #     stop_time = time.time()
18 #     print("函数运行时间是 %s " % (stop_time - start_time))
19 #
20 #
21 # test(foo)
22 # # 输出<function foo at 0x000002AE971CCE50>,函数接收的参数是一个函数名
23 # # Hello!
24 
25 # def foo():
26 #     print("from the foo")
27 #
28 #
29 # def test(func):
30 #     return func
31 #
32 #
33 # res = test(foo)
34 # # print(res) # <function foo at 0x0000020BAB04CE50>
35 # # res() # from the foo
36 
37 # 多运行了一步
38 import time
39 
40 
41 def foo():
42     time.sleep(3)
43     print("来自foo")
44 
45 
46 # 添加统计运行时间功能
47 # 不修改foo 源代码
48 # 不修改foo 调用方式
49 def timer(func):
50     start_time = time.time()
51     func() # 来自foo
52     stop_time = time.time()
53     print("函数的运行时间是 %s " % (stop_time - start_time))
54     return func
55 
56 
57 foo = timer(foo)
58 foo() # 来自foo
只有高阶函数满足不了装饰器

 函数嵌套

 1 # -*- coding:utf-8 -*-
 2 # @Time:2022/4/1 10:02
 3 # @Author:Henry Scofield
 4 # @File:6-函数嵌套.py
 5 # @Software:PyCharm
 6 # def bar():
 7 #     print("from bar")
 8 #
 9 #
10 # def foo():
11 #     print("from foo")
12 #
13 #     def test():
14 #         pass
15 def father(name):  # 一层一个包,封装完了,可以取里面的“变量”
16     print("from the father % s " % name)
17 
18     def son():
19         name = "David"  # name 作用域在son函数内
20         print("My daddy is % s " % name)
21 
22         def grandson():
23             name = "就是我自己"  # name 作用域在grandson函数内
24             print("My grandson is %s" % name)
25 
26         grandson()
27 
28     son()
29     # print(locals())  # 输出当前层的局部变量 # {'name': 'henry', 'son': <function father.<locals>.son at 0x000002103A01CD30>}
30 
31 
32 # 可以从最外层传一个参数,让里面这个包逐层执行这个参数
33 father('henry')
函数嵌套

 装饰器实现

 1 # -*- coding:utf-8 -*-
 2 # @Time:2022/4/1 10:25
 3 # @Author:Henry Scofield
 4 # @File:7-装饰器实现.py
 5 # @Software:PyCharm
 6 # 装饰器的框架
 7 import time
 8 
 9 
10 def timmer(func):  # func = test
11     def wrapper():
12         # print(func)  # timmer的func的内存地址
13         start_time = time.time()
14         func()  # 传进来的参数,就是在运行test()
15         stop_time = time.time()
16         print("运行时间是%s: " % (stop_time - start_time))
17 
18     return wrapper
19 
20 
21 @timmer  # @装饰器名,相当于 test = timmer(test)
22 def test():  # test:作为被修饰函数
23     time.sleep(3)
24     print("test函数运行完毕")
25 
26 
27 # 不修改被修饰函数test的源代码和调用方式添加新功能
28 
29 # res = timmer(test)  # 返回的是wrapper的地址
30 # res()  # 执行的是wrapper()
31 
32 # test = timmer(test)
33 # test()  # test函数运行完毕
34 # 运行时间是3.007908344268799:
35 
36 # @timmer 相当于 test = timmer(test)
37 
38 test()  # test函数运行完毕
39 # 运行时间是3.00045108795166:--->与上面结果一样的
装饰器实现
 1 # -*- coding:utf-8 -*-
 2 # @Time:2022/4/1 10:41
 3 # @Author:Henry Scofield
 4 # @File:8-装饰器加返回值.py
 5 # @Software:PyCharm
 6 # 装饰器的框架
 7 import time
 8 
 9 
10 def timmer(func):  # func = test
11     def wrapper():
12         start_time = time.time()
13         res = func()  # 传进来的参数,就是在运行test(),赋值给res,下面return 回res
14         stop_time = time.time()
15         print("运行时间是%s: " % (stop_time - start_time))
16         return res
17 
18     return wrapper
19 
20 
21 @timmer  # @装饰器名,相当于 test = timmer(test)
22 def test():  # test:作为被修饰函数
23     time.sleep(3)
24     print("test函数运行完毕")
25     return "这是test的返回值"
26 
27 
28 # wrapper 没加 return res前:
29 # res = test()  # 就是在运行wrapper
30 # print(res)  # 实际运行的是上面@timmer的返回值。返回None
31 
32 # wrapper 加 return res后:
33 res = test()
34 print(res)  # 返回的是test的返回值
函数闭包加返回值
 1 # -*- coding:utf-8 -*-
 2 # @Time:2022/4/1 10:51
 3 # @Author:Henry Scofield
 4 # @File:9-装饰器加参数.py
 5 # @Software:PyCharm
 6 # 装饰器的框架
 7 import time
 8 
 9 
10 def timmer(func):  # func = test
11     # def wrapper(name,age,gender): # wrapper加参数name,age # 被修饰的函数的参数不固定,不能单一地把wrapper的参数写死。
12     def wrapper(*args, **kwargs):  # test("henry",age=18) args = ("henry") kwargs={"age":18}
13         start_time = time.time()
14         # res = func(name,age,gender)  # 传进来的参数,就是在运行test(),赋值给res,下面return 回res
15         res = func(*args, **kwargs)
16         stop_time = time.time()
17         print("运行时间是%s: " % (stop_time - start_time))
18         return res
19 
20     return wrapper
21 
22 
23 @timmer  # @装饰器名,相当于 test = timmer(test)
24 def test(name, age):  # test:作为被修饰函数。test 加参数name,age
25     time.sleep(3)
26     print("test函数运行完毕,名字是 【%s】 年龄是 【%s】" % (name, age))
27     return "这是test的返回值"
28 
29 
30 # @timmer  # @装饰器名,相当于 test1 = timmer(test)
31 # def test1(name, age, gender):  # test:作为被修饰函数。test 加参数name,age
32 #     time.sleep(1)
33 #     print("test1函数运行完毕,名字是 【%s】 年龄是 【%s】 性别是 【%s】" % (name, age, gender))
34 #     return "这是test1的返回值"
35 #
36 #
37 # # 被修饰的函数的参数不固定,不能单一地把wrapper的参数写死。
38 # def test2(*args, **kwargs):
39 #     print(args)
40 #     print(kwargs)
41 
42 
43 def test2(name, age, gender): # test2(*('henry', 18, 'male', '还可以再传参数'))
44     # name, age, gender = ('henry', 18, 'male', '还可以再传参数') <-----相当于
45     print(name)
46     print(age)
47     print(gender)
48 
49 
50 def test1(*args, **kwargs): # 接收可变长度参数
51     test2(*args, **kwargs) # args= ('henry', 18, 'male', '还可以再传参数')
52 
53 
54 # wrapper 没加 return res前:
55 # res = test()  # 就是在运行wrapper
56 # print(res)  # 实际运行的是上面@timmer的返回值。返回None
57 
58 # wrapper 加 return res后:
59 # res = test('henry',18) # 就是在运行wrapper
60 # print(res)  # 返回的是test的返回值
61 # test1('henry', 18, 'male')  # 就是在运行wrapper
62 #
63 # test2(1, 2, 3, 4, name=3)
64 # 返回元组:(1, 2, 3, 4)
65 # 字典:{'name': 3}
66 
67 test1('henry', 18, 'male', '还可以再传参数') #
函数闭包加参数
 1 # -*- coding:utf-8 -*-
 2 # @Time:2022/4/7 14:22
 3 # @Author:Henry Scofield
 4 # @File:10-函数闭包加上认证功能.py
 5 # @Software:PyCharm
 6 """给所有的函数添加一个验证功能,不修改源代码"""
 7 
 8 
 9 def auth_func(func):
10     def wrapper(*args, **kwargs):
11         username = input("请输入您的用户名:").strip()
12         passwd = input("请输入您的密码:").strip()
13         if username == '产品经理' and passwd == '123':
14             res = func(*args, **kwargs)
15             return res
16         else:
17             print("用户名或密码错误!")
18 
19     return wrapper
20 
21 
22 @auth_func
23 def index():  # 首页
24     print("欢迎来到京东主页!")
25 
26 
27 @auth_func
28 def home(name):
29     print("%s欢迎回家!" % (name))
30 
31 
32 @auth_func
33 def shopping_car(name):
34     print("%s的购物车里有 [%s,%s,%s]" % (name, '奶茶', '土豆', '多啦A梦'))
35 
36 
37 index()
38 home('产品经理')
39 shopping_car('产品经理')
函数闭包加上认证功能

 

 函数闭包模拟session

 1 # -*- coding:utf-8 -*-
 2 # @Time:2022/4/7 14:38
 3 # @Author:Henry Scofield
 4 # @File:11-函数闭包模拟session.py
 5 # @Software:PyCharm
 6 """给所有的函数添加一个验证功能,不修改源代码"""
 7 
 8 user_list = [
 9     {'name': 'henry', 'passwd': '123'},
10     {'name': 'David', 'passwd': '456'},
11     {'name': 'Alice', 'passwd': '789'},
12     {'name': 'Taylor', 'passwd': '101112'},
13 ]
14 current_dic = {'username': None, 'login': False}
15 
16 
17 def auth_func(func):
18     def wrapper(*args, **kwargs):
19         if current_dic['username'] and current_dic['login']:  # 如果有用户名和登录密码,则直接返回函数,否则继续往下走
20             res = func(*args, **kwargs)
21             return res
22         username = input("请输入您的用户名:").strip()
23         passwd = input("请输入您的密码:").strip()
24         # for 循环遍历提取用户列表信息
25         for user_dic in user_list:
26             if username == user_dic['name'] and passwd == user_dic['passwd']:
27                 current_dic['username'] = username
28                 current_dic['login'] = True
29                 res = func(*args, **kwargs)
30                 return res
31 
32         else:
33             print("用户名或密码错误!")
34 
35     return wrapper
36 
37 
38 @auth_func
39 def index():  # 首页
40     print("欢迎来到京东主页!")
41 
42 
43 @auth_func
44 def home(name):
45     print("%s欢迎回家!" % (name))
46 
47 
48 @auth_func
49 def shopping_car(name):
50     print("%s的购物车里有 [%s,%s,%s]" % (name, '奶茶', '土豆', '多啦A梦'))
51 
52 
53 print("before-->",current_dic)
54 index()
55 print('after-->',current_dic)
56 home('产品经理')
57 shopping_car('产品经理')
简单用户登录案例

 

 

函数闭包带参数装饰器

 1 # -*- coding:utf-8 -*-
 2 # @Time:2022/4/7 14:38
 3 # @Author:Henry Scofield
 4 # @File:11-函数闭包模拟session.py
 5 # @Software:PyCharm
 6 """给所有的函数添加一个验证功能,不修改源代码"""
 7 
 8 user_list = [
 9     {'name': 'henry', 'passwd': '123'},
10     {'name': 'David', 'passwd': '456'},
11     {'name': 'Alice', 'passwd': '789'},
12     {'name': 'Taylor', 'passwd': '101112'},
13 ]
14 current_dic = {'username': None, 'login': False}
15 
16 
17 def auth(auth_type='filedb'):  # 添加认证类型
18     def auth_func(func):  # 认证功能
19         def wrapper(*args, **kwargs):
20             print("认证类型是:", auth_type)
21             if auth_type == 'filedb':  # 对认证类型作判断
22                 if current_dic['username'] and current_dic['login']:  # 如果有用户名和登录密码,则直接返回函数,否则继续往下走
23                     res = func(*args, **kwargs)
24                     return res
25                 username = input("请输入您的用户名:").strip()
26                 passwd = input("请输入您的密码:").strip()
27                 # for 循环遍历提取用户列表信息
28                 for user_dic in user_list:
29                     if username == user_dic['name'] and passwd == user_dic['passwd']:
30                         current_dic['username'] = username
31                         current_dic['login'] = True
32                         res = func(*args, **kwargs)
33                         return res
34                 else:
35                     print("用户名或密码错误!")
36 
37             elif auth_type == 'asdf':
38                 print("不是这样的认证类型!")
39                 res = func(*args, **kwargs)
40                 return res
41             else:
42                 print("认证类型都不对!")
43                 res = func(*args, **kwargs)
44                 return res
45 
46         return wrapper
47 
48     return auth_func  # 返回认证功能函数
49 
50 
51 @auth(auth_type='filedb')  # auth_func =auth(auth_type='filedb')-->@auth_func
52 def index():  # 首页
53     print("欢迎来到京东主页!")
54 
55 
56 @auth(auth_type='asdf')
57 def home(name):
58     print("%s欢迎回家!" % (name))
59 
60 
61 @auth(auth_type='123')
62 def shopping_car(name):
63     print("%s的购物车里有 [%s,%s,%s]" % (name, '奶茶', '土豆', '多啦A梦'))
64 
65 
66 # print("before-->", current_dic)
67 index()
68 # print('after-->', current_dic)
69 home('产品经理')
70 shopping_car('产品经理')
12-函数闭包带参数装饰器

 

posted on 2022-04-01 10:02  henry06007  阅读(24)  评论(0编辑  收藏  举报