zoukankan      html  css  js  c++  java
  • Python之旅的第3²+1天(文件操作、迭代器、生成器)

    今天计划看的一个关于昨天内容的博客最终还是没看,躺下的感觉总是那么爽,爽到你不想起床,但是早晨是例外的,因为精神可以控制肉体。

    首先是关于文件操作的补充:

    # 以字节形式读取文件:
    # f = open('test.txt','rb')  #注意:如果以字节形式读取文件,此时是不能设置encoding =
    # f.close()
    
    # 关于换行,当你以readlines读取文件的时候会获得
    ,但是Python会自动帮你转换为
    
    # 通过在打开文件后面设置上newline
    # f = open('test','r',encoding = 'utf-8')
    # print(f.readlines())   #输出结果:['第二行前面皮一下
    ', 'oujielun
    ', 'kobe
    ', '第二行前面皮一下
    ']
    # f.close()
    #
    # f = open('test','r+',encoding = 'utf-8',newline = '')
    # print(f.readlines())   #输出结果:['第二行前面皮一下
    ', 'oujielun
    ', 'kobe
    ', '第二行前面皮一下
    ']
    # f.close()
    #在open打开文件的时候设置newline默认参数为空后,Python就不会再自动将
    转换为
    
    #但是在使用seek方法的时候,计算字节数时,在Windows中依旧按照
    各自计算一个字节,即换行为两个字节
    
    #字节形式文件写入方法
    # f = open('test_1.txt','wb')    #字节形式写入不能设置encoding哦
    # f.write(bytes('你好啊',encoding = 'utf-8'))  #这里在使用bytes方法输出‘你好啊’对应字节码时是需要注明参考编码表的
    # f.close()
    
    #字节形式读取文件的方式
    # f = open('test_1.txt','rb')   #同理,字节形式读取也是不能在打开文件的时候设置encoding
    # data = f.read()
    # print(data)                  #输出结果:b'xe4xbdxa0xe5xa5xbdxe5x95x8a'('你好啊'的字节形式)
    # print(data.decode('utf-8'))  #输出结果:你好啊
    # f.close()
    
    #为什么会存在用字节形式读取文件的这种反人类操纵呢?
    #我们处理的文件可不仅仅是字符串的形式哦,还有很多照片、视频等文件
    #字节形式可以匹配一切设备,赞。
    
    #文件操作的其他方法
    #closed 检查文件是否关闭,有时候还是会忘记写f.close()
    #f.encoding  显示文件打开所参考的编码(和文件存贮的编码形式无关哦)
    #f.flust  刷新文件,相当于实现文件写入时定期的自动保存功能
    #f.name  获取文件名称(目前感觉好傻逼的方法啊)
    
    #f.tell 显示当前光标读取的所在位置(以字节形式反馈)
    # f = open('test','r+',encoding = 'utf-8')
    # print(f.readline())     #输出结果:'第二行前面皮一下',8个字用utf-8是24个字节,同时加上
    各占一个字节
    # print(f.tell())     #输出结果为:26   3*8+2
    # print(f.closed)     #输出Flase
    # f.close()
    #在文件中的所有读取方法中,只有read是按照字符数的个数进行移动光标,
    # /其他所有方法都是按照字节进行移动光标
    
    # f.seek 非常重要的一个方法,光标的移动
    # 书写的格式为f.seek(a,b)   #按照字节数移动光标
    # a表示光标移动的距离,b表示光标移动的方向
    # 不输入参数b:默认为0,表示从文件最开始的位置移动a个字节
    # b = 1 :表示从光标当前所在位置向后移动a个字节
    # b = 2 :表示光标从文件最后向前移动a个字节,此时的a必须是一个负数
    
    # seek的b值为默认的0时
    # f = open('test','r',encoding = 'utf-8')   #test文件内容
    # ['第二行前面皮一下
    ', 'oujielun
    ', 'kobe
    ', '第二行前面皮一下
    ']
    # print(f.readline())   #输出结果:第二行前面皮一下
    # f.seek(6)             #从文件开始向后移动6个字节
    # print(f.readline())   #此时输出的内容:行前面皮一下
    # f.close()
    
    # seek的b值等于1时,移动光标的相对位置
    # ['第二行前面皮一下
    ', 'oujielun
    ', 'kobe
    ', '第二行前面皮一下
    ']
    # f = open('test','rb')   #test文件内容,忘记了一个很重要的东西,要以字节的方式进行处理
    # f.seek(6,1)             #从文件开始向后移动6个字节
    # print((f.readline()).decode('utf-8'))   #此时输出的内容:行前面皮一下
    # f.seek(6,1)             #上一句的readline已经把光标移动到第二行的开端,现在从第二行开始向后移动6位
    # print((f.readline()).decode('utf-8'))   #此时输出的内容:'un',此时是第二行开始向后移动了6个字节
    # f.close()
    
    # b = 2 时的操作,记住此时的a一定是负数
    # f = open('test','rb')   #test文件内容
    # # ['第二行前面皮一下
    ', 'oujielun
    ', 'kobe
    ', '第二行前面皮一下
    ']
    # f.seek(-6,2)             #从最后向前移动6个字节
    # print((f.readline()).decode('utf-8'))     #此时输出的内容:'一下'
    # f.close()
    
    # seek的b值等于2时,是文件操作中唯一从后向前读取文件的方法
    # 可用于读取大规模文件的最后一行,比如大型网站的管理日志
    # f=open('test_1.txt','rb')
    #
    # for i in f:
    #     offs=-3
    #     n=0
    #     while True:
    #         f.seek(offs,2)
    #         data=f.readlines()
    #         if len(data) > 1:
    #             print('最后一行',data[-1].decode('utf-8'))
    #             break
    #         offs*=2
    
    # 加入没有seek方法,我们读取最后一行文件的方法
    # f = open('test_1.txt','rb')
    # data = f.readlines()    #这个创建list的过程会占用大量内存空间
    # print('最后一行',data[-1].decode('utf-8'))

    关于迭代器:

      迭代器的概念:

    #迭代器即迭代的工具,那什么是迭代呢?
    #迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值
    while True: #只是单纯地重复,因而不是迭代
        print('===>') 
        
    l=[1,2,3]
    count=0
    while count < len(l): #迭代
        print(l[count])
        count+=1

      为何要有迭代器?什么是可迭代对象?什么是迭代器对象?

    #1、为何要有迭代器?
    对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器
    
    #2、什么是可迭代对象?
    可迭代对象指的是内置有__iter__方法的对象,即obj.__iter__,如下
    'hello'.__iter__
    (1,2,3).__iter__
    [1,2,3].__iter__
    {'a':1}.__iter__
    {'a','b'}.__iter__
    open('a.txt').__iter__
    
    #3、什么是迭代器对象?
    可迭代对象执行obj.__iter__()得到的结果就是迭代器对象
    而迭代器对象指的是即内置有__iter__又内置有__next__方法的对象
    
    文件类型是迭代器对象
    open('a.txt').__iter__()
    open('a.txt').__next__()
    
    
    #4、注意:
    迭代器对象一定是可迭代对象,而可迭代对象不一定是迭代器对象

      迭代器对象的使用

    dic={'a':1,'b':2,'c':3}
    iter_dic=dic.__iter__() #得到迭代器对象,迭代器对象即有__iter__又有__next__,但是:迭代器.__iter__()得到的仍然是迭代器本身
    iter_dic.__iter__() is iter_dic #True
    
    print(iter_dic.__next__()) #等同于next(iter_dic)
    print(iter_dic.__next__()) #等同于next(iter_dic)
    print(iter_dic.__next__()) #等同于next(iter_dic)
    # print(iter_dic.__next__()) #抛出异常StopIteration,或者说结束标志
    
    #有了迭代器,我们就可以不依赖索引迭代取值了
    iter_dic=dic.__iter__()
    while 1:
        try:
            k=next(iter_dic)
            print(dic[k])
        except StopIteration:
            break
            
    #这么写太丑陋了,需要我们自己捕捉异常,控制next,python这么牛逼,能不能帮我解决呢?能,请看for循环

      for循环

    #基于for循环,我们可以完全不再依赖索引去取值了
    dic={'a':1,'b':2,'c':3}
    for k in dic:
        print(dic[k])
    
    #for循环的工作原理
    #1:执行in后对象的dic.__iter__()方法,得到一个迭代器对象iter_dic
    #2: 执行next(iter_dic),将得到的值赋值给k,然后执行循环体代码
    #3: 重复过程2,直到捕捉到异常StopIteration,结束循环

      迭代器的优缺点

    #优点:
      - 提供一种统一的、不依赖于索引的迭代方式
      - 惰性计算,节省内存
    #缺点:
      - 无法获取长度(只有在next完毕才知道到底有几个值)
      - 一次性的,只能往后走,不能往前退

     关于生成器:

      什么是生成器

    #只要函数内部包含有yield关键字,那么函数名()的到的结果就是生成器,并且不会执行函数内部代码
    
    def func():
        print('====>first')
        yield 1
        print('====>second')
        yield 2
        print('====>third')
        yield 3
        print('====>end')
    
    g=func()
    print(g) #<generator object func at 0x0000000002184360>

      生成器就是迭代器

    g.__iter__
    g.__next__
    #2、所以生成器就是迭代器,因此可以这么取值
    res=next(g)
    print(res)

      三元表达式

    #三元表达式
    name = input('>>>')
    if name == 'alex':
        print('sb')
    else:
        print('shuaige')
        
    #以上if段落可简写为
    print('sb') if name == 'alex' else print('shuaige')
    
    #貌似还有复杂写法,我得再看看

    其实还是引用了很多现成的内容,暂时就是这么些了,很多需要复习哦

  • 相关阅读:
    Can't remove netstandard folder from output path (.net standard)
    website项目的reference问题
    The type exists in both DLLs
    git常用配置
    Map dependencies with code maps
    How to check HTML version of any website
    Bootstrap UI 编辑器
    网上职位要求对照
    Use of implicitly declared global variable
    ResolveUrl in external JavaScript file in asp.net project
  • 原文地址:https://www.cnblogs.com/xiaoyaotx/p/12406167.html
Copyright © 2011-2022 走看看