zoukankan      html  css  js  c++  java
  • 装饰器,迭代器,生成器

    一、装饰器

    无参装饰器:

     1、示例1

     1 import time  #加载时间模块
     2 def war(name):  #定义装饰器
     3     def wari():  
     4         start = time.time()  #定义开始时间
     5         name()    #相当于执行下面的函数
     6         stop = time.time()    #定义结束时间
     7         print("run time is %s" %(stop-start))  #给原来函数加入的新功能
     8     return wari
     9 @war
    10 def info():
    11     time.sleep(3)
    12     print('we are famly!!')
    13 
    14 info()

    执行@war的时候就表示运行了war(name)这个函数,然后把下面的函数名赋值给name,就表示info=war(info),现在取到的只是info这个函数的内存地址,在装饰器上运行name()就相当于执行这个info()函数

    示例2

     1 def war(name):
     2     def wari(*args,**kwargs):
     3         start = time.time()
     4         name(*args,**kwargs)
     5         stop = time.time()
     6         print("run time is %s" %(stop-start))
     7     return wari
     8 @war
     9 def info():
    10     time.sleep(3)
    11     print('we are famly!!')
    12 
    13 @war
    14 def auth(name,password):
    15     time.sleep(2)
    16     print('login success!')
    17 
    18 @war
    19 def ero(x):
    20     time.sleep(1)
    21     print('hello %s' %x)
    22     
    23 info()
    24 
    25 auth('xyy',123)
    26 ero('xyp')

    有参装饰器:

    示例1

     1 def auth1(auth_type):
     2         def auth(func):
     3              def war(*args,**kwargs):
     4                  if auth_type == 'file':
     5                     name = input("username: ")
     6                     pwd =  int(input("password: "))
     7                     if name  == "xyy" and pwd == 123:
     8                         print("login successfull!")
     9                         func(*args,**kwargs)
    10                     else:
    11                         print("login error!")
    12                 elif auth_type == 'sql':
    13                     print('输入错误')
    14            return war 
    15        return auth
    16 
    17 
    18 @auth1(auth_type='sql') #write=auth(write)
    19 def write():
    20 print('welcome to my home!')
    21 write()

    二、迭代器
    1、例子1:有下标的类型

     1 l = ['a','b','c','d','e'] #定义一个列表
     2 i = l.__iter__() #生成一个迭代器
     3 
     4 while True: #循环这个生成器
     5   try: #监听
     6     print(i.__next__()) #循环取下一个值
     7 except StopIteration: #监听的关键字
     8   break    #退出循环
     9 
    10 或:
    11 i = 0
    12 while i < len(l):
    13   print(l[i])
    14   i += 1
    15 
    16 或:
    17 for i in l: #直接循环遍历一遍
    18   print(i)
    19 
    20 或:
    21 for i in range(len(l)): #先取下标的的长度再取对应的值
    22   print(l[i])    
    23 PS:try和except相当于一个if判断

    例子2:没下标的类型

    1 dic = {'a':1,'b':2,'c':3}
    2 i = dic.__iter__()
    3 while True:
    4   try:
    5     print(i.__next__())
    6 except StopIteration:
    7   break

    例子3:文件类型

    1 with open('war.txt','r+',encoding='utf8') as f:
    2 a = f.__iter__()
    3 while True:
    4   try:
    5     print(a.__next__(),end='')
    6 except StopIteration:
    7   break

    2、判断是否是可迭代和是否是迭代器:

     1 from collections import Iterable,Iterator #加载模块
     2 s = "xyyp"
     3 l = ['a','b','c']
     4 t = (1,2,3,4)
     5 d = {"s":1,"a":4}
     6 f = open('war.txt')
     7 (1)Iterable判断是否可迭代:
     8 print(isinstance(s,Iterable)) -->True
     9 print(isinstance(l,Iterable)) -->True
    10 print(isinstance(t,Iterable)) -->True
    11 print(isinstance(d,Iterable)) -->True
    12 print(isinstance(f,Iterable)) -->True
    13 (2)Iterator判断是否是迭代器:
    14 print(isinstance(s,Iterator)) -->False
    15 print(isinstance(l,Iterator)) -->False print(isinstance(t,Iterator)) -->False 
    16 print(isinstance(d,Iterator)) -->False 
    17 print(isinstance(f,Iterator)) -->True

    PS:只有文件是可迭代对象并且是迭代器。

    小结:
    迭代器优点:
    1,迭代器提供了一种不依赖于索引的取值方式,这样可以遍历那些没有索引的可迭代对象,比如:字典,集合,文件。
    2,迭代器于列表比较,迭代器是惰性计算的,更节省内存空间。

    迭代器缺点:
    1,无法获取迭代器的长度,使用不如列表索引取值灵活。
    2,一次性,只能往后取值,不能倒着取值

    三、生成器和协程函数

    1、生成器就是一个函数,这个函数内包含有yield这个关键字。

    2、生成器和和return的区别在于return只能返回一次函数的值就结束了,yield能返回多次值。

    3、yield把函数变成了生成器,生成器也就是迭代器。

    示例1:

     1 def count(x): #定义函数
     2   print('start count')
     3   while x > 0: #函数内容
     4   yield x    #返回值
     5   x -= 1
     6 print('done')
     7 
     8 g = count(5) #执行函数 并把返回值赋给一个变量,最后生成迭代器
     9 while True:    #while循环迭代器
    10   try:
    11     print(next(g))
    12 except StopIteration:
    13   break

    4、协程函数:
    示例1:

     1 def eater(name): #定义函数
     2   print('%s waiting food' %name)
     3   food_list=[] #定义空列表
     4   while True:
     5     food = yield food_list #yield返回值赋值给food
     6     print('%s get %s,to start eat' %(name,food))
     7     food_list.append(food) #每传入一个值添加到列表里面去
     8 
     9 e = eater('钢蛋') #生成迭代器
    10 print(next(e)) #输出迭代器内容
    11 print(e.send('包子')) #send传入的值可以直接赋给yield
    12 print(e.send('大葱包子'))
    13 print(e.send('大蒜包子'))
    14 print(e.send('韭菜包子'))

    小结:
    send和next()的区别:
    1、如果函数内yield是表达式形式(food=yield),那么必须先next触发函数的执行。
    2、二者的共同之处都可以让函数在上一次暂停的位置继续运行,不同之处在于send在触发下一次代码的执行时,会顺便给yield传一个值。

    四、面向过程函数编程:
    示例:

     1 import os #加载os模块
     2 def decorate(func): #定义next装饰器
     3   def t_layer(*args,**kwargs):
     4     res = func(*args,**kwargs)
     5     next(res)
     6     return res
     7   return t_layer
     8 
     9 @decorate #调用装饰器
    10 def path(target): #定义文件路径生成器
    11   while True:
    12     dir_name = yield
    13     g = os.walk(dir_name)
    14     for i in g:
    15       for x in i[-1]:
    16         file_path = "%s\%s" %(i[0],x)
    17         target.send(file_path)
    18 
    19 @decorate
    20 def opener(target): #定义读取文件内容的生成器
    21   while True:
    22     file_path = yield
    23     with open(file_path) as f:
    24       target.send((file_path,f))
    25 
    26 @decorate
    27 def cat(target):    #定义看文件内容的生成器
    28   while True:
    29     file_path,f = yield
    30     for line in f:
    31     target.send((file_path,line))
    32 
    33 @decorate
    34 def grep(pattern,target): #定义一个过滤文件内容的生成器
    35   while True:
    36     file_path,line = yield
    37     if pattern in line:
    38     target.send(file_path)
    39 
    40 @decorate
    41 def printer():    #定义输出指定文件路径的生成器
    42   while True:
    43     file_path =yield
    44     print(file_path)
    45 
    46 g = path(opener(cat(grep('xlinux',printer())))) #调用生成器
    47 g.send('D:\xyyp')

    优点:
      1、体系结构更加清晰。
      2、简化程序的复杂度。
    缺点:
      1、可扩展极其的差,所以面向过程的应用场景是:不需要经常变化的软件。

  • 相关阅读:
    关于QQ秀
    c#重点知识解答(五) 选择自 masterall 的 Blog
    c#.net常用函数和方法集 选择自 fineflyak 的 Blog
    JavaScript 中 substr 和 substring的区别
    C#重点知识详解(二) 选择自 masterall 的 Blog
    c#重点知识详解(六) 选择自 masterall 的 Blog
    转:一个男孩的自白
    win2003端口映射2003的路由与远程访问,做端口映射(转)
    渗透笔记(转载)
    win下配置的Apache+PHP+MySQL绿色版本(转)
  • 原文地址:https://www.cnblogs.com/xyp-blog123/p/7028892.html
Copyright © 2011-2022 走看看