• python--有参装饰器、迭代器


    有参装饰器的引入:

    import time
    import random
    from functools import wraps
    
    def timmer(func):
        @wraps(func)
        def wrapper():
            # wrapper.__doc__=func.__doc__
            start_time = time.time()
            func()
            stop_time = time.time()
            print('run time is %s' % (stop_time-start_time))
            # wrapper.__doc__=func.__doc__
        return wrapper
    
    @timmer
    def index():
        'index function'
        time.sleep(3)
        print('welcome to index page')
    
    # print(index.__doc__)
    index()
    print(index.__doc__)
    结果:
    welcome to index page
    run time is 3.000171661376953
    index function

    先来简单介绍一下functools.wraps。

          我们在使用 Decorator 的过程中,难免会损失一些原本的功能信息。而functools.wraps 则可以将原函数对象的指定属性复制给包装函数对象, 默认有 __module____name____doc__,或者通过参数选择。

    def foo():
        'foo function------------>'
        pass
    
    print(help(foo))
    结果:
    foo()
        foo function------------>
    
    None

    help函数python的一个内置函数(它是python自带的函数,任何时候都可以被使)。

    help函数能作什么:

           在使用python来编写代码时,会经常使用python 调用函数自带函数或模块,一些不常用的函数或是模块的用途不是很清楚,这时候就需要用到help函数来查看帮助。

    这里要注意下,help()函数是查看函数或模块用途的详细说明,而dir()函数是查看函数或模块内的操作方法都有什么,输出的是方法列表。

    怎么使用help函数查看python模块中函数的用法:

    help( )括号内填写参数,操作方法很简单。

    使用help函数查看帮助时需要注意哪些问题:

    1、查看一个模块的帮助
    >>>help('sys')
    之后它回打开这个模块的帮助文档

    2、查看一个数据类型的帮助
    >>>help('str')
    返回字符串的方法及详细说明

    >>>a = [1,2,3]
    >>>help(a)
    这时help(a)则会打开list的操作方法
    >>>help(a.append)
    会显示list的append方法的帮助

    下面来几个栗子:

    def foo():
        'foo fuction'
        print(foo.__doc__)
        foo.__doc__ = 'asdfasdfasdfasdfsadfasdfasdfsadfasdfasfas'
        pass
    
    print(help(foo))
    结果:
    Help on function foo in module __main__:
    
    foo()
        foo fuction
    
    None
    def foo():
        'foo fuction'
        print(foo.__doc__)
        foo.__doc__ = 'asdfasdfasdfasdfsadfasdfasdfsadfasdfasfas'
        pass
    
    print(foo.__doc__)
    结果:
    foo fuction
    def foo():
        'foo fuction'
        print(foo.__doc__)
        foo.__doc__ = 'asdfasdfasdfasdfsadfasdfasdfsadfasdfasfas'
        pass
    
    
    foo.__doc__ = 'abcdefg'
    print(foo.__doc__)
    结果:
    abcdefg
    def foo():
        'foo fuction'
        print(foo.__doc__)
        foo.__doc__ = 'asdfasdfasdfasdfsadfasdfasdfsadfasdfasfas'
        pass
    
    
    foo.__doc__ = 'abcdefg'
    print(help(foo))
    结果:
    Help on function foo in module __main__:
    
    foo()
        abcdefg
    
    None
    def foo():
        'foo fuction'
        print(foo.__doc__)
        foo.__doc__ = 'asdfasdfasdfasdfsadfasdfasdfsadfasdfasfas'
        pass
    
    foo()
    print(foo.__doc__)
    结果:
    foo fuction
    asdfasdfasdfasdfsadfasdfasdfsadfasdfasfas

    有参装饰器

    db_path=r'C:UsersAdministratorPycharmProjectsuntitled4db.txt'
    
    login_dic = {
        'user': None,
        'status': False,
    }
    def deco(auth_type='file'):
        def auth(func):
            def wrapper(*args, **kwargs):
                if auth_type == 'file':
                    if login_dic['user'] and login_dic['status']:
                        res = func(*args, **kwargs)
                        return res
    
                    name = input('your name: ')
                    password = input('your password: ')
                    with open(db_path, 'r', encoding='utf-8') as f:
                        user_dic = eval(f.read())
    
                    if name in user_dic and password == user_dic[name]:
                            print('login ok')
                            login_dic['user'] = name
                            login_dic['status'] = True
                            res = func(*args, **kwargs)
                            return res
                    else:
                        print('login err')
                elif auth_type == 'ldap':
                    print('ldap认证方式')
                elif auth_type == 'mysql':
                    print('mysql认证方式')
                else:
                    print('不知到的认证方式')
            return wrapper
        return auth
    
    @deco(auth_type='abc') #@auth #index=auth(index)
    def index():
        print('welcome to index')
    
    @deco(auth_type='ldap')
    def home(name):
        print('welcome %s to home page' % name)
    
    index()
    
    home('egon')
    结果:
    不知到的认证方式
    ldap认证方式
    def deco(auth_type='file'):
        def auth(func):
            def wrapper(*args,**kwargs):
                if auth_type == 'file':
                    print('文件的认证方式')
                elif auth_type == 'ldap':
                    print('ldap认证方式')
                elif auth_type == 'mysql':
                    print('mysql认证方式')
                else:
                    print('不知到的认证方式')
            return wrapper
        return auth
    
    @deco(auth_type='abc') #@auth #index=auth(index)
    def index():
        print('welcome to index')
    
    @deco(auth_type='ldap')
    def home(name):
        print('welcome %s to home page' % name)
    
    index()
    
    home('egon')
    结果:
    不知到的认证方式
    ldap认证方式

    思考:

    • 缓存多个不同网站的内容:
    • 思路:hash每个url,用得到的值做成文件名,一个网站一个文件名,
    • 然后每次根据传进来的url进行hash得到的结果去寻找文件

    迭代器

    • 迭代:
      1.  重复
      2. 下一次重复是基于上一次的结果

    '''
    python为了提供一种不依赖于索引的迭代方式,
    python会为一些对象内置__iter__方法
    obj.__iter__称为可迭代的对象
    '''

    obj.__iter__() 得到的结果就是迭代器

    得到的迭代器:既有__iter__又有一个__next__方法

    d={'a':1,'b':2,'c':3}
    
    i=d.__iter__() #i叫迭代器
    print(i)
    print(i.__next__())
    print(i.__next__())
    print(i.__next__())
    # print(i.__next__()) #StopIteration
    结果:
    <dict_keyiterator object at 0x0000000001DBF2C8>
    a
    b
    c 

    迭代器的优点:

    • 1:提供了一种不依赖于索引的取值方式
    • 2:惰性计算。节省内存

    迭代器的缺点:

    • 1:取值不如按照索引取值方便
    • 2:一次性的。只能往后走不能往前退
    • 3:无法获取长度

    迭代器的应用:

    •  1. 提供了一种不依赖索引的统一的迭代方法
    •  2. 惰性计算,比如取文件的每一行
    l = [1, 2, 3]
    for item in l: #i=l.__iter__()
        print(item)
    结果:
    1
    2
    3
     作业:
    2 编写日志装饰器,实现功能如:一旦函数f1执行,则将消息2017-07-21 11:12:11 f1 run写入到文件中
        注意:时间格式的获取
            import time
            time.strftime('%Y-%m-%d %X')
    
    3 判断下列数据类型是可迭代对象or迭代器
    
    s='hello'
    l=[1,2,3,4]
    t=(1,2,3)
    d={'a':1}
    set={1,2,3}
    f=open('a.txt')
    
    4 分别用依赖索引和不依赖索引两种方式迭代上述对象
    
    5 选做题:
        基于课上所讲网页缓存装饰器的基础上,实现缓存不同网页的功能
        要求,用户提交的不同url,都能缓存下来,对相同的url发起下载请求,优先从缓存里取内容
    答案:
    # 2 编写日志装饰器,实现功能如:一旦函数f1执行,则将消息2017-07-21 11:12:11 f1 run写入到文件中
    #     注意:时间格式的获取
    #         import time
    #         time.strftime('%Y-%m-%d %X')
    #
    # import time
    #
    # log_path=r'C:UsersAdministratorPycharmProjectsuntitledlog.txt'
    # def log_deco(func):
    #     def wrapper(*args,**kwargs):
    #         with open(log_path,'w') as f:
    #             func(*args, **kwargs)
    #             a = f.write(time.strftime('%Y-%m-%d %X'))
    #             return a
    #
    #         # res=func(*args,**kwargs)
    #         # return res
    #     return wrapper
    #
    # @log_deco
    # def f1():
    #     print('welcome to f1 page')
    #
    # f1()
    
    
    
    # 3 判断下列数据类型是可迭代对象or迭代器
    #
    # s='hello'
    # l=[1,2,3,4]
    # t=(1,2,3)
    # d={'a':1}
    # set={1,2,3}
    # f=open('a.txt')
    #
    #字符串,列表,元祖,字典,集合,文件都是可迭代对象,可以object.__iter__
    # s='hello'
    # s1=s.__iter__()
    # print(s1.__next__())
    # print(s1.__next__())
    # print(s1.__next__())
    # print(s1.__next__())
    # print(s1.__next__())
    
    
    # l=[1,2,3,4]
    # l1=l.__iter__()
    # print(l1.__next__())
    # print(l1.__next__())
    # print(l1.__next__())
    # print(l1.__next__())
    
    
    # t=(1,2,3)
    # t1=t.__iter__()
    # print(t1.__next__())
    # print(t1.__next__())
    # print(t1.__next__())
    
    
    # d={'a':1}
    # d1=d.__iter__()
    # print(d1.__next__())
    
    
    # set={1,2,3}
    # set1=set.__iter__()
    # print(set1.__next__())
    # print(set1.__next__())
    # print(set1.__next__())
    
    
    # f=open('a.txt')
    # f1=f.__iter__()
    # print(f1.__next__())
    # print(f1.__next__())
    # print(f1.__next__())
    # print(f1.__next__())
    # print(f1.__next__())
    # print(f1.__next__())
    
    
    # 4 分别用依赖索引和不依赖索引两种方式迭代上述对象
    # s='hello'
    # l=[1,2,3,4]
    # t=(1,2,3)
    # d={'a':1}
    # set={1,2,3}
    # f=open('a.txt')
    #
    #
    # for i1 in s:
    #     print(i1)
    #
    # i1=0
    # while i1<len(s):
    #     print(s[i1])
    #     i1+=1
    #
    #
    # for i2 in l:
    #     print(i2)
    #
    # i2=0
    # while i2<len(l):
    #     print(l[i2])
    #     i2+=1
    #
    #
    # for i3 in t:
    #     print(i3)
    #
    # i3=0
    # while i3<len(t):
    #     print(t[i3])
    #     i3+=1
    #
    #
    # for i4 in d:
    #     print(i4)
    
    
    
    # for i5 in set:
    #     print(i5)
    #
    
    # with open('a.txt','r',encoding='utf-8')as f:
    #     for line in f:
    #         print(line,end='')
    
    #
    # 5 选做题:
    #     基于课上所讲网页缓存装饰器的基础上,实现缓存不同网页的功能
    #     要求,用户提交的不同url,都能缓存下来,对相同的url发起下载请求,优先从缓存里取内容
  • 相关阅读:
    javascript之reduce()方法的使用
    微信小程序开发小结
    小程序解析html之富文本插件wxParse
    vue中复选框全选与反选
    vue好用的图片查看器(v-viewer插件)
    Vue利用canvas实现移动端手写板
    file上传图片,base64转换、压缩图片、预览图片、将图片旋转到正确的角度
    js中文输入法字符串截断
    js实现表单序列化的两种方法。
    JS实现剪切板添加网站版权、来源
  • 原文地址:https://www.cnblogs.com/metianzing/p/7045947.html
Copyright © 2020-2023  润新知