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]
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)) # []
迭代器协议
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,在迭代会报错
装饰器
迭代器
装饰器:本质就是函数,功能:为其他函数添加附加功能。
原则:
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 # -*- 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)
装饰器的知识储备
装饰器 = 高阶函数 + 函数嵌套 + 闭包
高阶函数
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('产品经理')