zoukankan      html  css  js  c++  java
  • 装饰器与生成器

    **多层装饰器**
    需求:执行index()前,先认证,认证完成后计算index函数执行的时间
    ```python
    dict = {'user':'egon', 'pwd':'123'}
    import time
    #装饰器
    def auth(func):

    def inner():
    user=input('用户名:').strip()
    pwd=input('密码:').strip()
    if user==dict['user'] and pwd==dict['pwd']:

    def bestinner(*args,**kwargs):
    start = time.time()
    res = func(*args, **kwargs)
    end = time.time()
    print('花费:%s' % (end - start))
    return res
    return bestinner

    else:
    print('用户名密码有误')
    return inner

    @auth
    def index():
    time.sleep(1)
    print('呵呵')
    return 'index返回值'
    index()()

    ```

    ```python
    import time
    user_dic = {'is_login':None}

    def outter(func): # func = 最原始的login函数的内存地址
    def get_time(*args, **kwargs): # args = ('egon',) kwargs = {}
    start = time.time()
    res = func(*args, **kwargs) # 最原始的login函数的内存地址() 直接调用 func('egon')
    end = time.time()
    print('func run time:%s'%(end-start))
    return res
    return get_time

    def login_auth2(data_source,x,t):
    # data_source = 'file'
    def login_auth(func):
    # func = index
    def inner(*args,**kwargs): # 这里的参数是跟被装饰函数的参数一一对应
    if user_dic['is_login']:
    res = func(*args, **kwargs)
    return res
    else:
    if data_source == 'file':
    username = input('please input your username>>>:').strip()
    password = input('please input your password>>>:').strip()
    if username == 'jason' and password == '123':
    user_dic['is_login'] = True
    res = func(*args,**kwargs)
    return res
    else:
    print('username or password error')
    elif data_source == 'MySQL':
    print('from MySQL')
    elif data_source == 'ldap':
    print('ldap')
    else:
    print('暂无该数据来源')
    return inner
    return login_auth

    # 装饰器在装饰的时候 顺序从下往上
    # 装饰器在执行的时候 顺序从上往下
    # res = login_auth2('MySQL')
    @login_auth2('file',1,2) # index = login_auth(get_time) index = inner函数的内存地址
    # @login_auth
    @outter # get_time = outter(index) index是最原始的index
    def index():
    time.sleep(1)
    print('index')
    return 'index'
    index()
    ```

    **生成器**
    ```python
    """
    生成器:用户自定义的迭代器,本质就是迭代器

    """
    def func():
    print('first')
    yield 666 # 函数内如果有yield关键字,那么加括号执行函数的时候并不会触发函数体代码的运行
    print('second')
    yield 777
    print('third')
    yield 888
    print('forth')
    yield
    yield
    # yield后面跟的值就是调用迭代器__next__方法你能得到的值
    # yield既可以返回一个值也可以返回多个值 并且多个值也是按照元组的形式返回
    g = func() # 生成器初始化:将函数变成迭代器
    print(g)
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())

    print(range(1,10))

    for i in range(1,10,2):
    print(i)
    ```


    ```python
    # yield支持外界为其传参
    def dog(name):
    print('%s 准备开吃'%name)
    while True:
    food = yield
    print('%s 吃了 %s'%(name,food))
    # def index():
    # pass

    # 当函数内有yield关键字的时候,调用该函数不会执行函数体代码
    # 而是将函数变成生成器
    # g = dog('egon')
    # g.__next__() # 必须先将代码运行至yield 才能够为其传值
    # g.send('狗不理包子') # 给yield左边的变量传参 触发了__next__方法
    # g.send('饺子')

    """
    yield
    1.帮你提供了一种自定义生成器方式
    2.会帮你将函数的运行状态暂停住
    3.可以返回值

    与return之间异同点
    相同点:都可以返回值,并且都可以返回多个
    不同点:
    yield可以返回多次值,而return只能返回一次函数立即结束
    yield还可以接受外部传入的值
    """
    ```

    ```python
    # 列表生成式
    # res = [i for i in range(1,10) if i != 4]
    # print(res)

    # res = (i for i in range(1,100000000) if i != 4) # 生成器表达式
    # print(res)
    # """
    # 生成器不会主动执行任何一行代码
    # 必须通过__next__触发代码的运行
    # """
    # print(res.__next__())
    # print(res.__next__())
    # print(res.__next__())
    # print(res.__next__())


    # 占内存
    # f = open('xxx.txt','r',encoding='utf-8')
    # data = f.read()
    # print(len(data))
    # f.close()


    # with open('xxx.txt','r',encoding='utf-8') as f:
    # # n = 0
    # # for line in f:
    # # n += len(line)
    # # print(n)
    # g = (len(line) for line in f)
    # # print(g.__next__())
    # # print(g.__next__())
    # # print(g.__next__())
    # # print(g.__next__())
    # print(sum(g))


    def add(n,i):
    return n+i
    def test():
    for i in range(4):
    yield i
    g=test()

    for n in [1,10]:
    g=(add(n,i) for i in g)
    # 第一次for循环g=(add(n,i) for i in test())

    # 第二次for循环g=(add(n,i) for i in (add(n,i) for i in test()))
    print(n)
    res=list(g)

    """
    for i in (add(10,i) for i in test()): 会执行所有的生成器内部的代码
    add(n,i)
    """

    #A. res=[10,11,12,13]
    #B. res=[11,12,13,14]
    #C. res=[20,21,22,23] 答案
    #D. res=[21,22,23,24]

    ```

  • 相关阅读:
    XNA游戏编程等
    DirectX游戏编程(一):创建一个Direct3D程序
    POJ 1163 The Triangle(简单动态规划)
    web前段canvasjs图表制作一
    ubuntu 使用mysql
    Nginx+ uWSGI +django进行部署
    matplotlib如何绘制直方图、条形图和饼图
    matplotlib animation
    matplotlib 画图中图和次坐标轴
    matplotlib subplot 多图合一
  • 原文地址:https://www.cnblogs.com/lishuaing/p/11349223.html
Copyright © 2011-2022 走看看