函数对象
一,函数
- 函数可以赋值
- 函数可以当成参数传给另一个函数
- 可以当成另一个函数的返回值
- 可以作为容器类型的元素
二,闭包常用于传参
传参的两种方式
-
- 函数普通传参
- 闭包
1 import requests 2 3 #方式一: 4 def get(url): 5 return requests.get(url).text 6 7 #方式二: 8 def page(url): 9 def get(): 10 return requests.get(url).text 11 return get
三,装饰器
在扩展函数功能的时候需要遵循的原则为:开放封闭原则
-
- 开放:指的是对扩展功能是开放的
- 封闭:指的是对修改源代码是封闭的
案例,为下列代码添加新的功能
1 import time 2 3 def index(): 4 time.sleep(3) 5 print('Welcome to the index page’) 6 return 200 7 8 index() #函数执行
优化1:
1 def timer(func): #这个参数func是可以让这个装饰器服务多个函数 2 def wrapper(*args,**kwargs): #参数更加灵活 3 start_time=time.time() 4 res=func(*args,**kwargs) #这个返回值也源代码相同 5 stop_time=time.time() 6 print('run time is %s' %(stop_time-start_time)) 7 return res 8 return wrapper
优化2(加上语法糖): 1 @deco3 2 @deco2 3 @deco1 #相当于执行装饰器,多个语法糖是从下到上进行执行 4 def index(): 5 pass

优化3:(加上wraps)
1 from functools import wraps 2 3 def timer(func): 4 """ 5 wrapper.__doc__=func.__doc__ 6 wrapper.__name__=func.__name_ 7 '''' 8 @wraps(func) #这一步相当于上面的步骤,是为了让信息与原函数相等 9 def wrapper(*args,**kwargs): 10 start_time=time.time() 11 res=func(*args,**kwargs) 12 stop_time=time.time() 13 print('run time is %s' %(stop_time-start_time)) 14 return res 15 return wrapper
优化四,三层优化器,建造第三层的目的是为了参数数量的自由
1 def outter(wb): 2 def outer(fun): 3 @functools.wraps(fun) 4 def timer(*args, **kwargs): 5 import time 6 time_start=time.time() 7 time.sleep(2) 8 res=fun() 9 time_stop=time.time() 10 print(time_stop-time_start) 11 12 if wb=='1': 13 print('你好') 14 else: 15 print('拜拜') 16 return res 17 return timer 18 return outer 19 20 @outter(5) #这样的话可以用语法糖的方式在这里添加其他参数 21 def index(): 22 time.sleep(3) 23 print('Welcome to the index page') 24 return 200
四,迭代器
定义:就是指迭代取值的工具,迭代是一个重复的过程,每次重复都是基于上一次的结果而继续的,单纯的重复并不是迭代
如果里面有__iter__就是可迭代的,可以用__next__进行取值。但是注意,同一个可迭代对象只能用__next__一次,第二次就什么取不出来的。
1 l=[1,2,3,4,5,6,7,8,9] 2 3 l=l.__iter__() 4 i=0 5 while i<9: 6 7 print(l.__next__()) 8 i+=1 9 print('>>>>>>>') 10 while i < 9: 11 print(l.__next__()) 12 i += 1 13 ************ 14 1 15 2 16 3 17 4 18 5 19 6 20 7 21 8 22 9 23 >>>>>>>
1,可迭代对象,内置有__iter__:
可迭代对象.__iter__():得到迭代器对象
2,迭代器对象:内置有__next__方法并且内置有__iter__方法
迭代器对象.__next__():得到迭代器的下一个值
迭代器对象.__iter__():得到迭代器本身,和原来一样
3,for循环的工作原理:for循环可以称之为迭代器循环
-
- d.__iter__()得到一个迭代器
- 迭代器.__next__()拿到一个返回值,然后将返回值赋予k
- 循环第二个步骤,直到抛出异常,即StopIteration,然后结束
4,分类
可迭代对象:列表、元组、集合、字典、字符串、文件对象
迭代器对象:文件对象
5,优缺点
优点:
-
- 为序列和非序列类型提供了一种统一的迭代取值方式。
- 惰性计算:迭代器对象表示的是一个数据流,可以只在需要时才去调用next来计算出一个值,就迭代器本身来说,同一时刻在内存中只有一个值,因而可以存放无限大的数据流,而对于其他容器类型,如列表,需要把所有的元素都存放于内存中,受内存大小的限制,可以存放的值的个数是有限的。
缺点:
-
-
除非取尽,否则无法获取迭代器的长度
- 只能取下一个值,不能回到开始,更像是‘一次性的’,迭代器产生后的唯一目标就是重复执行next方法直到值取尽,否则就会停留在某个位置,等待下一次调用next;若是要再次迭代同个对象,你只能重新调用iter方法去创建一个新的迭代器对象,如果有两个或者多个循环使用同一个迭代器,必然只会有一个循环能取到值。
-
6,生成器,就是自定义的迭代器
在函数内一旦存在yield关键字,调用函数并不会执行函数体代码,会返回一个生成器对象,该生成器就是迭代器
1 def fun(): 2 print('第一次') 3 yield 1 #这是类似于返回值,需要next进行调用 4 print('第二次') 5 yield 2 6 print('第三次') 7 yield 3 8 res=fun() 9 print(next(res)) 10 res=fun() 11 print(next(res)) 12 res=fun() 13 print(next(res))
7,yield(注意运行一次指针停留位置)的灵活使用
-
- 与send(使用时必须传值,在打印返回值的时候比较简便一些)
1 >>> def eater(): 2 ... print('Ready to eat') 3 ... while True: 4 ... food=yield 5 ... print('get the food: %s, and start to eat' %food) 6 7 8 >>> g=eater() # 得到生成器对象 9 >>> g 10 <generator object eater at 0x101b6e2b0> 11 >>> next(e) # 需要事先”初始化”一次,让函数挂起在food=yield,等待调用g.send()方法为其传值 12 Ready to eat 13 >>> g.send('包子') 14 get the food: 包子, and start to eat 15 >>> g.send('鸡腿') 16 get the food: 鸡腿, and start to eat 17 18 g.close #代表关闭
- 与send(使用时必须传值,在打印返回值的时候比较简便一些)
posted on 2024-02-04 04:21 我才是最帅的那个男人 阅读(12) 评论(0) 收藏 举报
浙公网安备 33010602011771号