zoukankan      html  css  js  c++  java
  • Python小知识点(3)--装饰器

    (1)装饰器含参数,被装饰函数不含(含)参数

    实例代码如下:

     

    import time
    # 装饰器函数
    def wrapper(func):
        def done(*args,**kwargs):
            start_time = time.time()
            func(*args,**kwargs)
            stop_time = time.time()
            print('the func run time is %s' % (stop_time - start_time))
        return done
    # 被装饰函数1
    @wrapper
    def test1():
        time.sleep(1)
        print("in the test1")
    # 被装饰函数2
    @wrapper
    def test2(name):    #1.test2===>wrapper(test2)   2.test2(name)==dome(name)
        time.sleep(2)
        print("in the test2,the arg is %s"%name)
    # 调用
    test1()
    test2("Hello World")

     

    (2)装饰器含有参数,被装饰函数含(不含)参数

    import time
    user,passwd = 'admin','admin'
    def auth(auth_type):
        print("auth func:",auth_type)
        def outer_wrapper(func):
            def wrapper(*args, **kwargs):
                print("wrapper func args:", *args, **kwargs)
                if auth_type == "local":
                    username = input("Username:").strip()
                    password = input("Password:").strip()
                    if user == username and passwd == password:
                        print("33[32;1mUser has passed authentication33[0m")
                        res = func(*args, **kwargs)  # from home
                        print("---after authenticaion ")
                        return res
                    else:
                        exit("33[31;1mInvalid username or password33[0m")
                elif auth_type == "ldap":
                    print("ldap链接")
            return wrapper
        return outer_wrapper
    @auth(auth_type="local") # home = wrapper()
    def home():
        print("welcome to home  page")
        return "from home"
    @auth(auth_type="ldap")
    def bbs():
        print("welcome to bbs  page"
    print(home()) #wrapper()
    bbs()

    总结:

    1)装饰器实质为函数内嵌,返回函数地址。

    2)装饰器带参数与不带参数相比装饰器带参数的多了一层函数定义用于接收装饰器中传递的参数,其余基本相同。

    3)先验证装饰器中的参数,在验证普通函数的参数

    小知识:

    列表生产式:[i for i in range(5)]---->[0,1,2,3,4,5]

    生成器与迭代器:

    第一种方式通过括号的方式生成

    生成器:()---i for i in range(5))  ==>generator

    这种一边循环一边计算的机制,称为生成器:generator

    生成器只有在调用时才会生成相应的数据,只记录当前位置。

    只有一个__next__()方法

    第二种方式通过yield生成

    在函数中使用yield即可将一个函数变为一个生成器

    迭代器:

    直接作用于for循环的数据类型:

    一类是集合数据类型,如listtupledictsetstr等;

    一类是generator,包括生成器和带yieldgenerator function

    直接作用于for循环的对象统称为可迭代对象:Iterable

    可以使用isinstance()判断一个对象是否是Iterable对象

    from collections import Iterable

     isinstance([], Iterable)=========true

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

    可以使用isinstance()判断一个对象是否是Iterator对象:

    >>> from collections import Iterator

    >>> isinstance((x for x in range(10)), Iterator)

    ======>True

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

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

    例如:iter([])<====迭代器

    PythonIterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

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

    小结:

    凡是可作用于for循环的对象都是Iterable类型;

    凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

    集合数据类型如listdictstr等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

     

  • 相关阅读:
    使用 linux kernel +busybox 定制linux系统
    记一次golang的内存泄露
    关于Queries_per_sec 性能计数器
    NUMA导致的MySQL服务器SWAP问题分析
    Drop Table对MySQL的性能影响分析
    当MySQL数据库遇到Syn Flooding
    tcp_tw_recycle参数引发的数据库连接异常
    一例数据同步异常问题分析
    MySQL大量线程处于Opening tables的问题分析
    MySQL DeadLock故障排查过程
  • 原文地址:https://www.cnblogs.com/wfaceboss/p/9425128.html
Copyright © 2011-2022 走看看