zoukankan      html  css  js  c++  java
  • python day14

    带参装饰器

    装饰器主要是为被装饰函数添加新功能,有时候也是需要外界提供的参数

    当需要外界提供参数时:

        1、装饰器函数(outer)只能有一个形参,为了让被装饰函数对象传进去

        2、装饰器内部的闭包函数(inner)的参数也是固定的和被装饰函数的参数一直

      --以上两个都靠不住的时候,我们就把整个装饰器作为一个整体,嵌套定义在另一个函数的内部,通过外部的函数对里面的函数进行传参

    def warps(info):
        def outer(func):
            def inner(*args, **kwargs):
                # 添加新功能   可以接收info进行操作
                res = func(*args, **kwargs)
                # 添加新功能
                return res  # 可以对结果进行修改
            return inner
        return outer   #把装饰器函数传到外界
    @warps(info)     #括号里面传参,函数遇到括号就执行,返回outer  
    def fn():           #所以实际上@warps(info) = @outer  和之前是一样的
        pass
    fn()

        系统的wraps带参装饰器,改变inner的假指向,本质上外界使用的还是inner,但是打印__doc__()和地址都改成wraps()括号里的函数。

    form functools import wraps

    def outer(func):

      @wraps(func)  # 改变inner的假指向,doc(文档注释)和地址假指func

      def inner(*args,**kwargs):

        res = func(*args,**kwargs)

        return res

      return inner

    迭代器

    #可迭代对象  可以通过某种方法得到迭代器对象

    #迭代器对象  可以不用依赖索进行取值的容器

        --迭代器的优点:可以不依赖索引进行取值

        --迭代器的缺点:取值只能从前到后取,不能取特定地方的值

    可迭代对象

    #可迭代对象:有__iter__()方法的对象是可迭代对象,可迭代对象调用__iter__()得到迭代器对象

    ls = [1,2,3,4]

    res = ls.__iter__()  ==>ls有iter的方法,所以ls(列表list)是可迭代对象

    直接访问res是访问  得到的迭代器对象  的地址

    #可迭代对象有哪些:字符串(str)、列表(list)、元组(tuple)、字典(dict)、集合(set)、  迭代器对象、生成器对象

    迭代器对象

    #迭代器对象:有__next__()方法的对象是迭代器对象,迭代器对象可以用__next__()方法进行取值

    with open('1.txt','rb') as f:

      res = f.__next__()  #文件中第一行的内容

      print(res)

      res = f.__next__()  #文件中第二行的内容

      print(res)

     #迭代器的对象有哪些:文件对象、枚举对象(enumerate(s))

    for循环迭代器

    #直接用while循环在迭代器对象中通过__next__()取值,终究会有取完的时候,取完再取

    就会抛出StopIteration异常

    ls = [1,2,3,4]
    iterator = ls.__iter__()        #先把ls变成迭代器对象
    while True:
        try:            #取完会报StopIteration异常,用try  except语法来捕捉异常
            print(iterator.__next__())      #通过while循环取值
        except StopIteration:   #捕捉到异常之后结束循环
            break

    所以for循环就是对while取迭代器的封装

    ls = [1,2,3,4]
    for v in ls:
        print(v)
    for v in ls.__iter__():     #->可迭代对象取完就是迭代器对象
        print(v)
    iterator = ls.__iter__()    #->迭代器对象取完就是本身    (三个循环取值的结果都是一样的)
    for v in iterator:
        print(v)

    for循环迭代器取值的工作原理

    for v in obj:pass

    #1、获取obj__iter__()的结果,  就是得到要操作的迭代器对象

    #2、迭代器对象通过__next__()方法进行取值,依次将当前循环的结果赋值给v

    #3、当取值抛出异常之后,自动处理StopIteration异常并结束循环

    枚举对象

    #给可迭代对象及迭代器添加迭代索引

    s = 'abc'

    for v in enumerate(s):

      print(v)  #(0,'a')  (1,'b')  (2,'c')

    生成器

    生成器:语法和函数相同,内部有yield关键字,函数名()得到的是生成器对象,生成器对象也有next方法所以:

            --生成器就是自定义的迭代器对象

                --就是用函数语法来声明生成器,用yield关键字取代return关键字来返回值,参数没有多少变化

    #执行流程

    def fn():

      yield 1      #从上往下执行,遇到一个yield返回一个值

      yield 2      #然后再取找下一个yield,再返回一个值

      yield 3      #如果找不到yield,就会抛异常stopiteration

                #和for连用的话for会自动处理Stopiteration异常并结束循环

    range()就是一个系统的生成器,我们也可以自己定义一个和range功能一样的生成器

  • 相关阅读:
    Python self,init,对象属性
    Python 注释,类,属性,方法,继承
    Python 循环与定义函数
    PHP中封装Redis购物车功能
    负数字符串经过int处理之后还是负数
    小程序模板template
    PHP里获取一维数组里的最大值和最小值
    Python缩进与if语句 空格的魅力
    maven 建立ssh项目
    tomcat war包部署
  • 原文地址:https://www.cnblogs.com/hesujian/p/10791775.html
Copyright © 2011-2022 走看看