函数对象

一,函数

  • 函数可以赋值
  • 函数可以当成参数传给另一个函数
  • 可以当成另一个函数的返回值
  • 可以作为容器类型的元素

二,闭包常用于传参

  传参的两种方式

    • 函数普通传参
    • 闭包
       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 #代表关闭

       

  

 

 

 

 

posted on 2024-02-04 04:21  我才是最帅的那个男人  阅读(12)  评论(0)    收藏  举报

导航