zoukankan      html  css  js  c++  java
  • python学习day4之路

    装饰器(http://egon09.blog.51cto.com/9161406/1836763)

    1、装饰器:本质是函数;

    装饰器(装饰其他函数),就是为其他函数添加附加功能;

    原则:1.不能修改被装饰函数的源代码;

       2.不能修改被装饰的函数的调用方式;

    装饰器对被装饰的函数完全透明的,没有修改被装饰函数的代码和调用方式。

    实现装饰器知识储备:

    1.函数即“变量”;

    2.高阶函数;

    3.嵌套函数

    高阶函数+嵌套函数=》装饰器

    匿名函数(lambda表达式)

    >>> calc = lambda x:x*3
    >>> calc(2)
    6

    高阶函数:

      a.把一个函数名当做实参传递给另外一个函数;

    >>> def bar():
      print("in the bar.....")  

    >>> def foo(func):

       print(func)
    >>> foo(bar)

    <function bar at 0x7f8b3653cbf8>  

      b.返回值中包含函数名;

    >>> import time

    >>> def foo():
      time.sleep(3)
      print("in the foo.....")
    >>> def main(func):
       print(func)
       return func
    >>> t = main(foo)
    <function foo at 0x7fb7dc9e3378>
    >>> t()
    in the foo.....

    装饰器:

    在不修改源代码的情况下,统计程序运行的时间:

    import time

    def timmer(func):
    def warpper(*args,**kwargs):   #warpper(*args,**kwargs)万能参数,可以指定参数,也可以不指定参数
    start_time = time.time() #计算时间
    func()
    stop_time = time.time()
    print("the func run time is %s" %(stop_time-start_time)) #计算函数的运行时间
    return warpper

    @timmer    #等价于test1 = timmer(test1),因此函数的执行调用是在装饰器里面执行调用的
    def test1():
    time.sleep(3)
    print("in the test1")

    test1()
    运行结果如下:

    in the test1
    the func run time is 3.001983404159546

    装饰器带参数的情况:

    import time

    def timmer(func):
    def warpper(*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 warpper    #返回内层函数名

    @timmer
    def test1():
    time.sleep(3)
    print("in the test1")

    @timmer    #test2 = timmer(test2)
    def test2(name):
    print("in the test2 %s" %name)

    test1()
    test2("alex")
    运行结果如下:

    in the test1
    the func run time is 3.0032410621643066
    in the test2 alex
    the func run time is 2.3603439331054688e-05

    装饰器返回值情况:

    import time
    user,passwd = "alex","abc123"
    
    def auth(func):
        def wrapper(*args,**kwargs):
            username = input("Username:").strip()
            password = input("Password:").strip()
    
            if user == username and passwd == password:
                print("33[32;1mUser has passed authentication.33[0m")
                return func(*args,**kwargs)   #实际上执行调用的函数   
                # res = func(*args,**kwargs)
                # return res   #函数返回值的情况,因为装饰器调用的时候是在装饰器调用的函数,因此返回值也在这个函数中
            else:
                exit("33[31;1mInvalid username or password.33[0m")
        return wrapper
    
    
    def index():
        print("welcome to index page...")
    
    @auth
    def home():
        #用户自己页面
        print("welcome to home page...")
        return "form home..."
    
    @auth
    def bbs():
        print("welcome to bbs page")
    
    index()
    print(home())
    bbs()

    装饰器带参数的情况:

    实现:1、本地验证;2、远程验证

    import time
    user,passwd = "alex","abc123"
    
    def auth(auth_type):
        '''函数的多层嵌套,先执行外层函数'''
        print("auth_type",auth_type)
        def out_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 authentication.33[0m")
                        func(*args,**kwargs)   #实际上执行调用的函数
                        # res = func(*args,**kwargs)
                        # return res   #函数返回值的情况,因为装饰器调用的时候是在装饰器调用的函数,因此返回值也在这个函数中
                    else:
                        exit("33[31;1mInvalid username or password.33[0m")
                elif auth_type == "ldap":
                    print("搞毛线lbap,傻逼....")
            return wrapper
        return out_wrapper
    
    
    def index():
        print("welcome to index page...")
    
    @auth(auth_type="local")
    def home():
        #用户自己页面
        print("welcome to home page...")
        return "form home..."
    
    @auth(auth_type="ldap")
    def bbs():
        print("welcome to bbs page")
    
    index()
    home()
    bbs()   #函数没有,因为没有调用函数,函数的调用在装饰器里面,是装饰器调用了函数

       迭代器和生成器

      生成器

      通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

      所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

      >>> l1 = (i for i in range(10))
      >>> l1
      <generator object <genexpr> at 0x7f6a9fbcaeb8>
      >>> l1.__next__()
      0
      >>> l1.__next__()
      1
      生成器:只有在调用时才会生成相应的数据;

      只有通过__next__()方法进行执行,这种能够记录程序运行的状态,yield用来生成迭代器函数。(只能往后调用,不能向前或者往后推移,只记住当前状态,因此银行的系统用来记录的时候可以使用yield函数)。

    '''利用yield实现异步的效果,发送接收消息'''
    import time
    
    def consumer(name):
        '''消费者吃包子模型'''
        print("%s准备吃包子了......" %name)
        while True:
            '''循环,由于没有终止'''
            baozi = yield
            print("包子%s被%s吃了......" %(baozi,name))
    
    
    def producer(boss):
        '''生产者生产包子模型,生产者要生产包子'''
        c1 = consumer("A")
        c2 = consumer("B")
        c1.__next__()
        c2.__next__()
        '''接下来,生产者要生产包子了,并传递给消费者'''
        for i in range(1,10):
            time.sleep(1)
            c1.send(i)
            c2.send(i)
    
    producer("Alex")

    运行如下:
    A准备吃包子了......
    B准备吃包子了......
    包子1被A吃了......
    包子1被B吃了......
    包子2被A吃了......
    包子2被B吃了......
    包子3被A吃了......
    包子3被B吃了......
    包子4被A吃了......
    包子4被B吃了......
    包子5被A吃了......
    包子5被B吃了......
    包子6被A吃了......
    包子6被B吃了......
    包子7被A吃了......
    包子7被B吃了......
    包子8被A吃了......
    包子8被B吃了......
    包子9被A吃了......
    包子9被B吃了.....

      迭代器

      我们已经知道,可以直接作用于for循环的数据类型有以下几种:

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

      一类是generator,包括生成器和带yield的generator function。

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

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

    >>> from collections import Iterable
    >>> isinstance([], Iterable)
    True
    >>> isinstance({}, Iterable)
    True
    >>> isinstance('abc', Iterable)
    True
    >>> isinstance((x for x in range(10)), Iterable)
    True
    >>> isinstance(100, Iterable)
    False
     
     
  • 相关阅读:
    SpringSource Tools Suite 字体偏小问题
    Ubuntu11.10 Eclipse 提示框 为黑色 解决方案
    图的广度优先搜索 皇星客栈
    哈夫曼编码 皇星客栈
    m_hWnd与this指针 皇星客栈
    建立中序线索二叉树 皇星客栈
    第一部分 整数Hash 皇星客栈
    哈夫曼树建立 皇星客栈
    Hash入门 皇星客栈
    stdin,stdout 和STDOUT_FILENO,STDIN_FILENO的学习 皇星客栈
  • 原文地址:https://www.cnblogs.com/gengcx/p/7107728.html
Copyright © 2011-2022 走看看