• Python Day13-14


    一.上周回顾复习·

      函数:

    1.函数名的本质  —— 就是一个变量 里面存储了函数的内存地址   函数名可以作为函数的参数、返回值。可以被赋值,可以作为可变数据类型的元素

    2.函数的定义

    ~参数——形参:

            位置参数

      *args

      默认参数

      **kwargs

    ~返回值 return

      返回值为None

      返回一个值,这个值可以是任意数据类型

      返回多个值,多个值之间用逗号隔开,以元组的形式返回

    3.函数调用

    ~参数——实参:

      按照位置传参

      按照关键字传参

    ~获取返回值

      接收返回值

      不接受返回值    

    4.函数的应用 ——闭包函数

      在内部函数中使用了外部函数的变量,这个内部函数就叫做闭包

    5.作用域——全局作用域,局部作用域

      全局作用域内的变量可以被局部作用域使用

     a = 1
     def func():
         print(a)
    
     func()
    
    输出结果
    1

      在局部作用域内定义的变量不能在全局作用域使用

     def func_b():
         b = 20   #b是局部作用域中的变量
    
     func_b()
     print(b)    #报错:在全局作用域中不能使用局部作用域的变量

      关于global关键字:

    c = 10
    def func_c1():
        c = 20
        print('in func_c1',c)
    func_c1()
    print(c)
    输出结果
    in func_c1 20
    10

    加入global关键字以后:

    c = 10
    def func_c2():
        global c
        c = 20
        print('in func_c2',c)
    func_c2()
    print(c)
    输出结果
    in func_c2 20
    20

    ~命名空间:内置、全局、局部

    6.装饰器  —— 函数的应用

    #def wrapper(func):
    # def inner(*args,**kwargs):
    # '''在执行被装饰的函数之前要做的事情'''
    # ret = func(*args,**kwargs)
    # '''在执行被装饰的函数之后要做的事情'''
    # return ret
    # return inner     (必背!)

     

    @wrapper 
    def func():
    pass        @wrapper 语法糖表示 func = wrapper(func)

    .迭代器

    1.迭代器 就是实现了能从其中一个一个的取出值来

    ~只要包含了“双下iter”方法的数据类型就是可迭代的 —— 可迭代协议
    数据类型和python解释器定下来的协议

    ~'__iter__'   这个方法导致了一个数据类型的可迭代

    ~迭代器中有 __next__ 和 __iter__方法  —— 迭代器协议

    ~在python里 你学过的所有的可以被for循环的 基本数据类型 都是可迭代的 而不是迭代器

    lst_iterator = [1,2,3].__iter__()
    print(set(dir(lst_iterator)) - set(dir([1,2,3])))
    
    输出结果
    
    
    {'__length_hint__', '__setstate__', '__next__'}

    2. 可迭代对象

    ~可迭代协议:含有__iter__方法的对象

    ~迭代器协议:含有__iter__和__next__方法的对象

    3.迭代器和可迭代对象之间的关系

    ~可迭代对象包含迭代器 

      那么可迭代对象是如何成为迭代器的? 

          迭代器 = 可迭代对象.__iter__()    

    **可迭代对象并不能用,它是变成迭代器以后才能用的

        怎么用呢?

      

    lst_iterator = [1,2,3].__iter__()
    print(lst_iterator.__next__())
    print(lst_iterator.__next__())
    print(lst_iterator.__next__())  
    #迭代器中[1,2,3]打印三个没有了再打印就会报错
    输出结果
    
    1
    2
    3

    ~for 可以是一个可迭代对象 也可以是一个迭代器

      如果 for循环的内容是一个可迭代的对象时,它就会自动的去调用可迭代对象的__iter__方法获取到一个迭代器

    ~为什么要有迭代器 迭代器存在的本质是什么:

       1.能够对python中的基本数据类型进行统一的遍历,不需要关心每一个值分别是什么
       2.它可以节省内存 —— 惰性运算

       f = open('file','w')     文件句柄就是一个迭代器

      range(10000000).__iter__()   range就是一个可迭代的对象

    ~迭代器:

        1.天生的,比如文件句柄

       2.后天的,可迭代对象.__iter__()

    三.  生成器  Iterator 迭代器  Gerator 生成器

    1.生成器就是迭代器,生成器是我们自己写出来的

    2.生成器分类

      ~生成器函数:生成器函数可以通过常规的def语句定义,不同的是,不是使用return返回,而是用yield一次返回一个结果,在每个结果之间挂起和继承它们的状态,来自动实现迭代协议。
      

      ~生成器表达式:类似于列表推导,但,生成器返回按需生产结果的一个对象,而不是一次构建一个结果列表。

    3.什么时候用到生成器??

       当创建列表只是一共中间过程的时候,为了避免创建庞大的列表,我们可以使用生成器表达式来完成

    • 生成器是可迭代对象;
    • 实现了延迟计算,省内存(按需执行);
    • 生成器本质和其他类型一样,都是实现了迭代器协议,只不过生成器是一边计算,一边生成,从而节省内存空间,其余的可迭代对象可没有这个功能。
    def generator_func():  #生成器函数
        print(123)
        yield 'aaa'   #return
        print(456)
        yield 'bbb'
    g = generator_func()        #generator生成器  - 生成器的本质就是迭代器
    ret = g.__next__()
    print(ret)
    ret2 = g.__next__()
    print(ret2)
    g = generator_func()
    print(list(g))
    
    输出结果
    
    123
    aaa
    456
    bbb
    123
    456
    ['aaa', 'bbb']

    **带yield关键字的函数就是生成器函数

    **生成器函数在执行的时候只返回一个生成器,不执行生成器函数中的内容

    **从生成器中取值:

      1.__next__ 有几个yield就可以取几次
      2.for循环取值 正常取 for i in g:
      3.其他数据类型进行强制转换 list(g) 返回一个列表,里面装着生成器中的所有内容
      注意:调用生成器函数的时候,要先获取生成器,再进行next取值
        生成器中的内容只能取一次,且按顺序取值没有回头路,取完为止。

    def generator():
        yield
        yield 2
    g = generator()
    for i in g:
        print(i)
    
    输出结果
    
    none
    
    2

    进阶示例

    def get_clothing():
        for cloth in range(1,2000000):
            yield '第%s件衣服'%cloth
    g = get_clothing()
    print(g.__next__())
    for i in range(20):
        print(g.__next__())
    
    
    输出结果
    
    第1件衣服
    第2件衣服
    第3件衣服
    第4件衣服
    第5件衣服
    第6件衣服
    第7件衣服
    第8件衣服
    第9件衣服
    第10件衣服
    第11件衣服
    第12件衣服
    第13件衣服
    第14件衣服
    第15件衣服
    第16件衣服
    第17件衣服
    第18件衣服
    第19件衣服
    第20件衣服
    第21件衣服
    import time
    def tail(filename):
        f = open(filename,encoding='utf-8')
        f.seek(0,2)   #将文件的光标移到最后
        while True:
            line = f.readline()
            if not line:
                time.sleep(0.1)
                continue
            yield line
    
    tail_g = tail('demo')
    for line in tail_g:
        print(line,end='')

    四.最后的总结:

    1.可迭代对象   内部有__iter__

    2.迭代器    内部有__iter__ __next__

    3.生成器 就是迭代器

    自己写的迭代器
    生成器函数 yield /yield from
    生成器表达式

    def generator_func(): #生成器函数
    print(123)
    yield 'aaa' #return
    print(456)
    yield 'bbb'

        



     

        

         

  • 相关阅读:
    linux设置网关修改ip
    Linux Source命令及脚本的执行方式解析
    ARM9 S3C2440 定时器中断
    Linux下配置静态IP地址,设置DNS和主机名
    s3c2440外部中断操作
    vmware中为虚拟机添加硬盘空间
    『SHELL』SHELL脚本执行方式
    WCF开发的几个频骤
    MyEclipse下Axis2插件的下载和安装
    WCF系列(二) 使用配置文件构建和使用WCF服务
  • 原文地址:https://www.cnblogs.com/liuduo/p/7474279.html
Copyright © 2020-2023  润新知