zoukankan      html  css  js  c++  java
  • python基础之迭代器生成装饰器

    基本概念

    1.容器(container)

    容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用innot in关键字判断元素是否包含在容器中。通常这类数据结构把所有的元素存储在内存中(也有一些特例,并不是所有的元素都放在内存,比如迭代器和生成器对象)在Python中,常见的容器对象有:

    • list, deque, ….
    • set, frozensets, ….
    • dict, defaultdict, OrderedDict, Counter, ….
    • tuple, namedtuple, …
    • str

    容器比较容易理解,因为你就可以把它看作是一个盒子、一栋房子、一个柜子,里面可以塞任何东西。从技术角度来说,当它可以用来询问某个元素是否包含在其中时,那么这个对象就可以认为是一个容器,比如 list,set,tuples都是容器对象.

    2.可迭代对象(iterable)

    凡是可以返回一个迭代器的对象都可称之为可迭代对象

    3.迭代器(iterator)

    那么什么迭代器呢?它是一个带状态的对象,他能在你调用next()方法的时候返回容器中的下一个值,任何实现了__iter____next__()方法的对象都是迭代器,__iter__返回迭代器自身,__next__返回容器中的下一个值,如果容器中没有更多元素了,则抛出StopIteration异常,至于它们到底是如何实现的这并不重要。

    生成器(generator)

    一个包含了yield关键字的函数就是一个生成器,该函数也叫生成器函数。当生成器函数被调用时,在函数体中的代码不会被执行,而会返回一个迭代器。每次请求一个值,就会执行生成器中代码,直到遇到一个yield表达式或return语句。yield表达式表示要生成一个值,return语句表示要停止生成器。换句话说,生成器是由两部分组成,生成器的函数和生成器的迭代器。生成器的函数是用def语句定义的,包含yield部分;生成器的迭代器是这个函数返回的部分。二者合起来叫做生成器。

     迭代器与生成器

    1.迭代器使用举例:

    复制代码
    city = ['beijing','shanghai','tinajin','chongqin']
    it = iter(city)
    print(type(it))
    #方法一:使用next方法来使用迭代器
    print(it.__next__())
    print(it.__next__())
    
    方法二:使用for循环来使用迭代器
    for x in it:
        print(x)
    复制代码

    2 用生成器函数完成与counter类似功能

    复制代码
    def generator(low,high):
        while low <= high:
            yield low
            low += 1
    for i in generator(1,10):
        print(i,end='')
    
    
    结果:12345678910
    复制代码

    3. 生成器产生无限多的值

    复制代码
    def generator(start = 0):
        while True:
            yield start
            start += 1
    for number in generator(4):
        print(number,end='')
        if number > 20:
            break
    复制代码

     4. 列表生成器

    a = [i*2 for i in range(1,10)]
    print(a)
    
    结果: [2, 4, 6, 8, 10, 12, 14, 16, 18]

     装饰器

     要求:
     不能修改被装饰的函数的源代码
     不能修改被装饰的函数的调用方式
     满足上面的两种情况下给程序增添功能
    
     组成:
     < 函数+实参高阶函数+返回值高阶函数+嵌套函数+语法糖 = 装饰器 >

     1.简单装饰器

    复制代码
     1 import time
     2 def timer(func):
     3     def wrapper():
     4         start_time = time.time()
     5         func()
     6         stop_time = time.time()
     7         print("run time %s"%(stop_time-start_time))
     8     return wrapper
     9 @timer      #语法糖  test=timer(test)
    10 def test():
    11     time.sleep(3)
    12     print("in the test")
    13 test()
    14
    15 结果:
    16 in the test
    17 run time 3.000171661376953。
    复制代码
    1.test表示的是函数的内存地址
    2.test()就是调用对在test这个地址的内容,即函数
    
    高阶函数:
    1.把一个函数名当作实参传给另外一个函数(“实参高阶函数”)
    2.返回值中包含函数名(“返回值高阶函数”)
    这里面所说的函数名,实际上就是函数的地址,把函数名当做实参,那么也就是说可以把函数传递到另一个函数,然后在另一个函数里面做一些操作。
    
    嵌套函数:
    嵌套函数指的是在函数内部定义一个函数,而不是调用
    函数只能调用和它同级别以及上级的变量或函数。也就是说:里面的能调用和它缩进一样的和他外部的,而内部的是无法调用的。
    
    把test作为参数传递给了timer(),此时,在timer()内部,func = test,接下来,定义了一个wrapper()函数,但并未调用,只是在内存中保存了,并且
    标签为wrapper。在timer()函数的最后返回wrapper()的地址wrapper。然后再把wrapper赋值给了test,那么此时test已经不是原来的test了,也就是test原来的那些函数体的标签换掉了,换成了wrapper

    2.装饰有参函数

    复制代码
    import time
    
    def timer(func):
        def deco(*args,**kwargs):
            start_time = time.time()
            func(*args,**kwargs)
            stop_time = time.time()
            print(stop_time-start_time)
        return deco
    
    @timer
    def test(parameter):
        time.sleep(3)
        print("test is running")
    test("添加参数")
    复制代码

    3.更复杂的装饰器

    对这两个函数分别统计运行时间,再加一层函数来接受参数,根据嵌套函数的概念,要想执行内函数,就要先执行外函数,才能调用到内函数

    复制代码
    import time
    
    def timer(parameter):
    
        def outer_wrapper(func):
    
            def wrapper(*args, **kwargs):
                if parameter == 'task1':
                    start = time.time()
                    func(*args, **kwargs)
                    stop = time.time()
                    print("the task1 run time is :", stop - start)
                elif parameter == 'task2':
                    start = time.time()
                    func(*args, **kwargs)
                    stop = time.time()
                    print("the task2 run time is :", stop - start)
    
            return wrapper
    
        return outer_wrapper
    
    @timer(parameter='task1')
    def task1():
        time.sleep(2)
        print("in the task1")
    
    @timer(parameter='task2')
    def task2():
        time.sleep(2)
        print("in the task2")
    
    task1()
    task2()
  • 相关阅读:
    Eclipse 远程调试
    大数据处理方法bloom filter
    sicily 1259 Sum of Consecutive Primes
    sicily 1240. Faulty Odometer
    sicily 1152 简单马周游 深度优先搜索及回溯算法
    sicily 1050 深度优先搜索解题
    sicily 1024 邻接矩阵与深度优先搜索解题
    sicily 1156 二叉树的遍历 前序遍历,递归,集合操作
    sicily 1443 队列基本操作
    sicily 1006 team rankings 枚举解题
  • 原文地址:https://www.cnblogs.com/zhichao123/p/11234134.html
Copyright © 2011-2022 走看看