• Python学习笔记十 IO编程


    参考教程:廖雪峰官网https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000

    IO编程

    IO在计算机中指Input/Output,也就是输入和输出。比如你打开浏览器,访问网页,浏览器就需要通过网络IO获取网页信息。浏览器首先会发送数据给服务器,告诉它我想要首页的HTML,这个动作是往外发数据,叫Output,随后新浪服务器把网页发过来,这个动作是从外面接收数据,叫Input。所以,通常,程序完成IO操作会有Input和Output两个数据流。当然也有只用一个的情况,比如,从磁盘读取文件到内存,就只有Input操作,反过来,把数据写到磁盘文件里,就只是一个Output操作。IO编程中,Stream(流)是一个很重要的概念,Input Stream就是数据从外面(磁盘、网络)流进内存,Output Stream就是数据从内存流到外面去。对于浏览网页来说,浏览器和服务器之间至少需要建立两个通道,才可以既能发数据,又能收数据。

    一、文件读写

    在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。

    (一)读文件

    Python内置的open()函数可以打开一个文件对象:

     f = open('/Users/michael/test.txt', 'r')

    其中第二个参数'r'表示以读(read)的方式打开。如果文件不存在,这个函数就会抛出一个IOError的错误。

    如果文件打开成功,则可以继续调用read()方法把文件内容一次全部读取到内存:

    f.read()

    返回的是文件内容组成的一个字符串。

    在使用完文件后必须用close()关闭文件。否则文件对象会占用操作系统资源。

    文件读写过程都会可能产生IOError,所以可以使用try...finally..语句:

    try:
        f=open('...','r')
    finally:
        if f:
            f.close()

    如果觉得这些代码繁琐,也可以使用with语句,并且with语句后面不用调用close()方法:

    with open('test','r') as f:
        print(f.read())

    调用read()会一次性读取文件的全部内容,如果文件有10G,内存就爆了,所以,要保险起见,可以反复调用read(size)方法,每次最多读取size个字节的内容。另外,调用readline()可以每次读取一行内容,调用readlines()一次读取所有内容并按行返回list。因此,要根据需要决定怎么调用。如果文件很小,read()一次性读取最方便;如果不能确定文件大小,反复调用read(size)比较保险;如果是配置文件,调用readlines()最方便:

    for line in f.readlines():
        print(line.strip()) 

     二进制文件

    前面提到的文件都是文本文件,并且必须是UTF-8编码的文本文件,如果要读取二进制文件,比如图片、视频等,则需要用'rb'模式打开文件:

    with open("1.jpg",'rb') as f:
        print(f.read(8))

    字符编码

    如果要读取非UTF-8的文本文件,需要给open()传入encoding参数:

    #指定为GBK编码
    open('....txt', 'r', encoding='gbk')

    如果遇到有些编码不规范的文件,可能会出现UnicodeDecodeError错误,遇到这种情况,可以给open()函数增加设置一个errors参数,表示遇到编码错误后如何处理,如下:忽略是其中一种处理的方式:

    open('/Users/michael/gbk.txt', 'r', encoding='gbk',errors='ignore')

    写文件
    写文件和读文件的唯一区别是在调用open()函数时,传入标识符'w'或'wb'表示写文本文件或者写二进制文件:

    open('/Users/michael/gbk.txt', 'w')
    f.write("Hello World!")

    当我们写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。只有调用close()方法时,操作系统才保证把没有写入的数据全部写入磁盘。忘记调用close()的后果是数据可能只写了一部分到磁盘,剩下的丢失了。所以,还是用with语句来得保险:

    with open('....txt','w') as f:
          f.write("HELLO WORLD!")

    同样如果需要写入特定编码的文本文件,需要给open()函数传入encoding参数,将字符串自动转换成指定编码。
    另外,当以'w'模式写入文件时,如果文件已经存在,会直接覆盖原有内容。那么需要传入'a'以追加模式写入文件。

    with open("1.txt",'a') as f:
        f.write('i love nieson!
    ')
    with open("1.txt",'r') as f:
        print(f.read())

    二、StringIO和BytesIO

    (一)StringIO

    有时候不一定是针对文件的读写,也可以在内存中创建虚拟文件进行读写,StringIO就提供了这种方式。

    要把str写入StringIO,我们需要先创建一个StringIO,然后即可像文件一样操作:

    from io import StringIO
    f=StringIO()   #创建一个StringIO文件
    f.write('hello')
    f.write(' world!')   #注意这里第二次写入不会覆盖,直接append
    print(f.getvalue())  #注意这里用getvalue()获得写入的str

    上述的最后一句代码也可以用以下代码替换:

    f.seek(0)
    print(f.read()) 

    要读取StringIO,可以先用一个str初始化,然后再类似于读取文件一样:

    f=StringIO("Hello!
    Hi!
    GoodBye!")
    while True:
        s=f.readline()
        if s=='':
            break
        print(s.strip())

    (二)BytesIO

    StringIO操作的是str,如果要直接操作二进制数据,需要使用BytesIO,操作类似于StringIO:

    from io import BytesIO
    f=BytesIO()    #创建一个ByteIO文件
    f.write('中文'.encode('utf-8'))   #写入“中文”的UTF-8编码
    print(f.getvalue())       #输出编码
    
    f=BytesIO(b'x11xaaxf0x98x99')   #直接创建一个包含二进制数据的ByteIO文件
    print(f.read())      #读取二进制数据

     三、操作文件和目录

    Python内置的os模块可以直接调用操作系统提供的接口函数:

    import os
    print(os.name)  #打印操作系统信息
    import os
    
    print(os.path.abspath('-@-'))  #打印当前目录的绝对路径,以参数符号结尾
    #在某个目录下创建一个新目录,首先要用os.path.join()把新目录完整路径表示出来
    print(os.path.join('D:STUDYworkspacePythonLXF','testdir'))
    #第二步再创建这个目录
    os.mkdir('D:\STUDY\workspace\PythonLXF\testdir')
    
    #删除一个目录的操作:
    os.rmdir('D:\STUDY\workspace\PythonLXF\testdir')

    os.path.splitext()可以直接得到文件扩展名:

    os.path.splitext('/path/to/file.txt')
    
    #返回:('/path/to/file', '.txt')

    重命名和删除文件的操作:

    # 对文件重命名:
    os.rename('test.txt', 'test.py')
    # 删掉文件:
    os.remove('test.py')

    os.listdir():返回指定路径下的文件和文件夹的列表,参数为指定路径,默认为当前目录:

    import os
    import os.path
    
    for f in os.listdir():
        print(f)

     四、序列化

    程序运行过程,所有变量都是存储在内存中,一旦程序结束,变量所占用的内存就会被回收。Python中可以把变量从内存中变成可存储或传输的信息,这个过程称为序列化即picking。

    序列化之后,就可以把序列化的内容写入磁盘,或者通过网络传输到其他设备。反过来,把变量内容从序列化的对象重新读取到内存的过程称之为反序列化,即unpicking。

    Python提供了pickle模块来实现序列化。

    pickle.dumps()函数可以将任意对象(参数)序列化成一个bytes,然后就可以把这个bytes写入文件。

    pickle.dump()函数有两个参数,第一个为需要序列化的对象,第二个为写入的目的文件,可以直接把序列化后的内容写入一个文件。

    import pickle
    d=dict(name='Bob',age=20,score=88)
    pickle.dumps(d)   #把变量d序列化
    print(pickle.dumps(d))   #打印序列化的信息
    
    #以二进制写入方式打开文件
    f=open('dump.txt','wb')
    #将序列化信息写入文件对象
    pickle.dump(d,f)
    f.close()
    #以二进制读取方式打开文件
    f=open('dump.txt','rb')
    print(f.read())
    f.close()

    反之,pickle.loads()方法反序列化对象,先把内容读到一个bytes中作为参数传入方法;也可以直接用pickle.load()方法从一个文件对象中直接反序列化出对象。

    import pickle
    f=open('dump.txt','rb')
    #使用pickle.loads()其参数必须为一个序列化的内容
    print(pickle.loads(f.read()))
    f.seek(0)
    #使用pick.load()其参数可以直接为一个存放序列化内容的文件对象
    d=pickle.load(f)
    print(d)
    f.close()

    序列化的方法(形式)有很多种,一般采用JSON标准可以被所有语言读取,也可以方便的存储和传输,也可以直接在Web页面读取。

    JSON表示的对象就是标准的JavaScript语言的对象。

    Python 内置的json模块提供了Python对象到JSON的格式转换。

    以下示例为将一个Python对象编程一个JSON格式对象:

    import json
    d=dict(name='Bob',age=20,score=88)
    #输出:'{"name": "Bob", "age": 20, "score": 88}'
    print(json.dumps(d))

    这里json.dumps()方法返回一个字符串,字符串的内容就是标准格式的JSON。

    类似的,json.dump()方法可以把这个字符串直接写入一个文件中。

    f=open('t1.txt','w')
    json.dump(d,f)
    f.close()

    当要把JSON反序列化为Python对象时,就需要json.loads()或json.load()方法:

    import json
    f=open('t1.txt','r')
    print(json.loads(f.read()))
    f.seek(0)
    print(json.load(f))
    f.close()
  • 相关阅读:
    JS 简易模拟Promise.all
    JS 监听浏览器当前页签(Tab页)的切换(可见性变化)事件
    常用浏览器的UserAgent信息
    Why relationships must be equal?
    JS数组的洗牌方法
    React.memo 与 React.useMemo 的区别
    Vite版本从2.6.x升级到2.7.x之后,Vant从3.3.0升级到3.3.(1n)之后,项目构建时报错
    JS 模拟 Array.prototype.flat
    js排序(冒泡排序,插入排序,快速排序,选择排序)
    oracle操作
  • 原文地址:https://www.cnblogs.com/tsembrace/p/8698033.html
Copyright © 2020-2023  润新知