zoukankan      html  css  js  c++  java
  • Python基础(8)-装饰器、生成器、迭代器

    1.装饰器

    在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。本质上,decorator就是一个返回函数的高阶函数

    1)正常函数

    #!/usr/local/bin/python3
    import time
    
    def is_Prime(num):
        if num < 2:
            return True
        elif num ==  2:  
            return False
        else:
            for i in (2,num):
                if num % i == 0:
                    return False
            return True
    
    def find_Prime():
    	t1 = time.time()
        for i in range(2,10000):
            if is_Prime(i):
                print(i)
    	t2 = time.time()
    	print(t2-t1)
    	
    find_Prime()

    2)装饰器,无参数,无返回值

    #!/usr/local/bin/python3
    import time
    def display_time(func):
        def wrapper():
            t1 = time.time()
            func()
            t2 = time.time()
            print(t2-t1)
        return wrapper
    	
    def is_Prime(num):
        if num < 2:
            return True
        elif num ==  2:  
            return False
        else:
            for i in (2,num):
                if num % i == 0:
                    return False
            return True
    
    @display_time
    def find_Prime():
        for i in range(2,10000):
            if is_Prime(i):
                print(i)
    
    find_Prime()
    

    3)装饰器,有返回值

    #!/usr/local/bin/python3
    import time
    def display_time(func):
        def wrapper():
            t1 = time.time()
            result = func()
            t2 = time.time()
            print(t2-t1)
    	return result
        return wrapper
    	
    def is_Prime(num):
        if num < 2:
            return True
        elif num ==  2:  
            return False
        else:
            for i in (2,num):
                if num % i == 0:
                    return False
            return True
    
    @display_time
    def find_Prime():
      count = 0 for i in range(2,10000): if is_Prime(i): count +=1
      return count

    find_Prime()

    4)装饰器,有参数

    def display_time(func):
        def wrapper(n):
            t1 = time.time()
            result = func(n)
            t2 = time.time()
            print(t2-t1)
            return result
        return wrapper
    	
    def is_Prime(num):
        if num < 2:
            return True
        elif num ==  2:  
            return False
        else:
            for i in (2,num):
                if num % i == 0:
                    return False
            return True
    		
    @display_time
    def find_Prime(n):
        count = 0 
        for i in range(2,n):
            if is_Prime(i):
                count += 1
        return count
    
    find_Prime(10000)
    

    2. 生成器

    通过列表生成式,可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。比如我要循环100万次,按py的语法,for i in range(1000000)会先生成100万个值的列表。但是循环到第50次时,我就不想继续了,就退出了。但是90多万的列表元素就白为你提前生成了。

    for i in range(1000000):
        if i == 50: 
            break
        print(i)
    

    如上,for i in range(1000000)会先生成100万个值的列表。但是循环到第50次时,程序退出了,但是90多万的列表元素已经提前生成了,上述做法,不仅会占用很大的存储空间,而且绝大数元素占用的空间也浪费了。

    在Python中,这种一边循环一边计算后面元素的机制,称为生成器:generator。

    # 生成器创建
    (x * x for x in range(10))
    

    通过next()函数获得generator的下一个返回值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。通过for循环来迭代它,就不需要关心StopIteration的错误

    g = (x * x for x in range(10))
        for n in g:
            print(n)    
    

    3.函数生成器

    def fib(max):
        a,b = 0,1
        n = 0  # 斐波那契数
        while n < max:
            n = a + b
            a = b # 把b的旧值给到a
            b = n # 新的b = a + b(旧b的值)
            #print(n)
            yield n # 程序走到这,就会暂停下来,返回n到函数外面,直到被next方法调用时唤醒
    f = fib(100) # 注意这句调用时,函数并不会执行,只有下一次调用next时,函数才会真正执行
    
    print(f)
    print(f.__next__())
    print(f.__next__())
    print(f.__next__())
    print(f.__next__())
    
    >>>输出结果:
    第1个print:
    第2个print:1
    第3个print:2
    第4个print:3
    第5个print:5

    这就是定义generator的另一种方法。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:

    generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句暂停并返回数据到函数外,再次被next()调用时

    从上次返回的yield语句处继续执行

    4.迭代器

    可以直接作用于for循环的对象统称为可迭代对象:Iterable,可迭代的意思就是可遍历、可循环

    可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。

    生成器都是Iterator对象,但listdictstr虽然是Iterable,却不是Iterator

    listdictstrIterable变成Iterator可以使用iter()函数

    为什么listdictstr等数据类型不是Iterator

    这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()

    数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

    Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

      

  • 相关阅读:
    linux 中的./configuration --prefix=安装路径 的用法(指定源码安装方式的安装路基)
    深入了解Activiti工作流流程定义
    ResultCode 自定义错误状态码
    maven和gradle对比
    js中的prototype原型解析
    json字符串的标准格式
    迷茫于Hibernate/JPA的人提一些建议。
    ModelDriven 和 Preparable 拦截器
    Spring中bean的scope
    spring配置文件详解以及beans:beans标签
  • 原文地址:https://www.cnblogs.com/Iceredtea/p/10225944.html
Copyright © 2011-2022 走看看