zoukankan      html  css  js  c++  java
  • python基础语法8 叠加装饰器,有参装饰器,wraps补充,迭代器

    叠加装饰器:

      叠加装饰器
        - 每一个新的功能都应该写一个新的装饰器
        - 否则会导致,代码冗余,结构不清晰,可扩展性差

      在同一个被装饰对象中,添加多个装饰器,并执行。
      @装饰1
      @装饰2
      @装饰3
      def 被装饰对象():
        pass

      注意: 装饰器在调用被装饰对象时才会执行添加的功能。

      - 叠加装饰器:
        - 装饰的顺序: 由下到上装饰
        - 执行的顺序: 由上往下

      注意: 无论inner中出现任何判断,最后都要返回“调用后的被装饰对象” func(*args, **kwargs)

    def wrapper1(func):
        def inner1(*args, **kwargs):
            print('1---start')
            # 被裝飾對象在調用時,如果還有其他裝飾器,會先執行其他裝飾器中的inner
            # inner2
            res = func(*args, **kwargs)
            print('1---end')
            return res
        return inner1
    
    def wrapper2(func):
        def inner2(*args, **kwargs):
            print('2---start')
            res = func(*args, **kwargs)
            print('2---end')
            return res
        return inner2
    
    def wrapper3(func):
        def inner3(*args, **kwargs):
            print('3---start')
            res = func(*args, **kwargs)
            print('3---end')
            return res
        return inner3
    '''
    叠加裝飾器的裝飾順序與執行順序:
        - 裝飾順序: 调用wrapper装饰器拿到返回值inner
            由下往上裝飾
            
        - 執行順序: 调用装饰过后的返回值inner
            由上往下執行
    '''
    
    @wrapper1  # index《---inner1 = wrapper1(inner2)
    @wrapper2  # inner2 = wrapper2(inner3)
    @wrapper3  # inner3 = wrapper3(index)
    def index():  # 被裝飾對象   # inner1 ---》
        print('from index...')
    
    # 正在装饰
    index = wrapper3(index)
    index = wrapper2(index)
    index = wrapper1(index)
    
    '''
    inner1()
    inner2()
    inner3()
    index()
    '''
    index()  # 此处执行 # inner1() --> inner2() ---> inner3()

    有参装饰器

    # 无参装饰器: 装饰在被装饰对象时,没有传参数的装饰器。
    '''
    # 以下是无参装饰器
    @wrapper1  # inner1 = wrapper1(inner2)
    @wrapper2  # inner2 = wrapper2(inner3)
    @wrapper3
    '''
    
    # 有参装饰器: 在某些时候,我们需要给用户的权限进行分类
    '''
    # 以下是有参装饰器
    @wrapper1(参数1)  # inner1 = wrapper1(inner2)
    @wrapper2(参数2)  # inner2 = wrapper2(inner3)
    @wrapper3(参数3)
    '''
    def user_auth(user_role):  # 'SVIP'
        def wrapper(func):
            def inner(*args, **kwargs):
                if user_role == 'SVIP':
                    # 添加超级用户的功能
                    res = func(*args, **kwargs)
                    return res
                elif user_role == '普通用户':
                    print('普通用户')
                    # 添加普通用户的功能
                    res = func(*args, **kwargs)
                    return res
    
            return inner
        return wrapper
    
    
    # 被装饰对象
    user_auth('SVIP')
    等价于下面两行代码
    wrapper = user_auth('普通用户')
    @wrapper
    
    # @user_auth('SVIP')  # wrapper = user_auth('普通用户')
    #@wrapper  #<--- 返回结果(wrapper) <---- user_auth()
    def index():
        pass
    
    # wrapper = user_auth('普通用户')    等价于这两行
    # index=wrapper(index)
    
    index()

    wraps: (了解)
      是一个修复工具,修复的是被装饰对象的空间。不用显示外层装饰器注释
      from functools import wraps

    from functools import wraps
    
    
    def wrapper(func):
    
        @wraps(func)  # 修改名称空间: inner ---》 func   不写此处变为装饰器注释
        def inner(*args, **kwargs):
            '''
            此处是装饰器的注释
            :param func:
            :return:
            '''
            res = func(*args, **kwargs)
            return res
        return inner  # ---》 func
    
    
    @wrapper
    def index():
        '''
        此处是index函数的注释
        :return:
        '''
        pass
    
    
    print(index)  # 函数对象
    
    # 函数对象.__doc__: 查看函数内部的注释
    print(index.__doc__)  # inner.__doc__

    迭代器

    - 迭代器
      迭代的工具。

      迭代:
        迭代指的是重复迭代,每一次迭代都是基于上一次的结果而来的。

      迭代器:
        迭代器指的是迭代取值的工具,它可以迭代取值。

      - 如果想要知道python中迭代器是什么?必须先知道什么是可迭代对象?

      可迭代对象: 所有的序列类型: str, list, tuple, dict, set, f
        凡是内部有str.__iter__()方法的都是可迭代对象。

      - 获取迭代器:
        通过可迭代对象.__iter__(), 得到的返回值就是 “迭代器对象”。
        迭代器是迭代取值的工具,作用是迭代取值。

        - 如何迭代取值:
          迭代器对象.__next__() # “每一次执行”,都会从迭代器对象中取出一个值

      - 总结: 可迭代对象 VS 迭代器对象:
       - 获取可迭代对象: 定义序列类型(str, list, set, tuple, dict, f)
        - 特点:
          内置有__iter__()

      - 获取迭代器对象: 通过可迭代对象调用.__iter__()得到返回值
        - 特点:
          内置有__next__()

      - 迭代器对象的优点:
        - 优点:
          1.不依赖于索引迭代取值。
          2.节省内存空间。

        - 缺点:
          1.取指定某个值麻烦
          2.每次取值都要从第一个值开始,无法同过索引取值。

          3.不能通过len计算长度

    # 以下都是可迭代对象
    '''
    str1 = 'hello tank!'
    str1.__iter__()
    list1 = [1, 2, 3]  # list([1, 2, 3])
    list1.__iter__()
    set.__iter__()
    dict.__iter__()
    tuple.__iter__()
    open('a.txt').__iter__()
    '''
    # list1是一个可迭代对象
    list1 = ['tank', 'jason鸡哥', 'sean', '饼哥']
    
    # 获取迭代器对象: iter_list1
    iter_list1 = list1.__iter__()
    
    while True:
        # 补充: try: 捕获异常
        try:
            print(iter_list1.__next__())  # 报错
    
        # 立即触发此处代码 StopIteration
        except StopIteration:
            break
    测试迭代文件
    f = open('user.txt', 'r', encoding='utf-8')
    iter_f = f.__iter__()
    
    while True:
        try:
            print(iter_f.__next__())
    
        except StopIteration:
    
            break

    for循环本质

    for循环原理
      语法: for i in 可迭代对象:
      in: 可迭代对象 ----> 内部会自动调用.__iter__() ---> 迭代器对象

      for i in 可迭代对象:
      # 会自定帮你调用__next__
      print(i)
      # for循环内部也会有一个捕获异常机制,一旦遇到异常也会停止取值。

    list1 = [1, 2, 3, 4]
    
    for line in list1:  # list1是可迭代对象 ----> 内部会自动调用.__iter__() ---> 迭代器对象
        # 迭代器对象.__next__()
        print(line)

    迭代器对象

    - 迭代器本质上是一个可迭代对象

    - 文件本质上既是迭代器对象,也是可迭代对象。

    - 可迭代对象不一定是迭代器对象

    iter_set1 = set1.__iter__()
    iter_set1.__next__()
    
    # 确定: 迭代器对象也是一个可迭代对象
    # 判断可迭代对象是否是迭代器对象
    # print(iter_set1.__iter__() is iter_set1)  # True
    
    # 唯独文件比较特殊: 因为文件从读取出来的时候就是一个迭代器对象
    # f ---> 可迭代对象, 还是迭代器对象
    # f = open('user.txt', 'r', encoding='utf-8')
    # f.__next__()
    #
    # # # 确定: 文件既是可迭代对象,也是迭代器对象。
    # # # iter_f ---> 迭代器对象
    # iter_f = f.__iter__()
    # iter_f.__next__()
    '''
    list1 = [1, 2, 3]
    # 迭代器对象
    iter_list = list1.__iter__()
    
    str1 = '123'
    # 迭代器对象
    iter_str1 = str1.__iter__()
    
    print(iter_list is iter_str1)  # False
    '''
    
    # 可迭代对象
    list1 = [1, 2, 3, 4]
    
    # iter_list1 ---> 迭代器对象
    iter_list1 = list1.__iter__()
    print(iter_list1 is list1)  # False
    # 可迭代对象不一定是迭代器对象
  • 相关阅读:
    python搭建开发环境
    django初探
    linux下安装Composer
    文件记录追加 file_put_content
    自定义导出表格
    异步处理接口 fsockopen
    appcache checking update
    js pix
    Event Aggregator
    ko list and css gradient
  • 原文地址:https://www.cnblogs.com/ludingchao/p/11851812.html
Copyright © 2011-2022 走看看