美文网首页
Python 系统、IO、序列化

Python 系统、IO、序列化

作者: 李霖弢 | 来源:发表于2020-01-16 15:34 被阅读0次

    注意,python中各种相对路径都相对于项目的工作目录,默认情况下即为项目的启动目录

    读写文件

    读写文件是最常见的IO操作。Python内置了读写文件的函数,用法和C是兼容的。

    • 默认以encoding='utf-8'打开文件
    • errors可以设为ignore忽略或设为replace通过namereplace指定字符替换不支持的转码
    • .seek(0)移动指针到头部
    • r读取 r+读写 指针在头部
    • w写入 w+读写 指针在尾部
    • a追加写入 a+追加读写 指针在尾部
    • x创建写入(文件已存在则报错)
    f = open('/Users/michael/test.txt', 'w+', encoding='utf-16', errors='replace')
    f.write("hello")
    f.seek(0)
    print(f.read())
    

    当我们写文件时,操作系统可能会放到内存缓存起来,空闲的时候再慢慢写入。只有调用close()方法时,操作系统才保证把没有写入的数据全部写入磁盘。
    由于文件读写时都有可能产生IOError,一旦出错,后面的close就不会调用,应保证无论是否出错都能正确地关闭文件:

    try:
        f = open('/path/to/file', 'r')
        print(f.read())
    except BaseException as err:
        print(err)
    finally:
        if f:
            f.close()
    

    或使用with语句无论是否出错都会自动调用close()方法:

    with open('/path/to/file', 'r') as f:
        print(f.read())
    
    从当前指针处向后读

    调用read会一次性读取文件的全部内容(但如内容过多会超出内存)
    调用read(size)方法,每次最多读取size个字节
    调用readline()每次读取一行
    调用readlines()一次读取所有内容并按行返回list

    for line in f.readlines():
        print(line.strip()) # 把末尾的'\n'删掉
    
    二进制文件

    要读取二进制文件,比如图片、视频、文件等,用带b的模式打开或输入即可:

    with open(fileName, 'wb') as activeFile:
        for chunk in res.iter_content(len(res.content)):
            activeFile.write(chunk)
    

    内存中读写

    在内存中创建的file-like Object,常用作临时缓冲。
    通过getvalue可以获取到完整内容(无视指针位置)
    write写入的内容可以互相叠加,但会覆盖初始化时的内容

    StringIO

    读写str

    from io import StringIO
    f = StringIO('A')
    f.write('B')
    f.write('C')
    print(f.getvalue())#BC
    
    BytesIO

    读写bytes

    from io import BytesIO
    f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')
    print(f.getvalue())#b'\xe4\xb8\xad\xe6\x96\x87'
    f.seek(0)
    print(f.read())#b'\xe4\xb8\xad\xe6\x96\x87'
    

    OS

    查看操作系统信息
    import os
    >>>os.name
    Linux/Unix/Mac为posix,Windows为nt。
    >>>os.environ
    查看系统环境变量
    
    路径操作
    • os.chdir(path)
      改变工作目录

    • os.path.abspath(path)
      传入绝对/相对路径并返回绝对路径,如传入.则返回当前项目工作目录的绝对路径,传入__file__则返回该代码所在文件的绝对路径

    • os.path.dirname(path)
      传入文件路径,获取其所在目录的绝对路径

    • os.listdir(path)
      传入目录路径,返回目录下所有文件/目录名的list

    • os.path.isdir(path) 和 os.path.isfile(path)
      判断是否为目录/文件

    • os.walk(path)
      可以创建一个生成器,用以遍历该目录及其所有后代目录下的所有文件

      • root 所指的是当前正在遍历的目录的自身地址
      • dirs 是一个 list ,内容是当前正在遍历的目录中所有子目录的名字(不深入查找)
      • files 同样是 list , 内容是当前正在遍历的目录中所有的文件(不深入查找)
    for root, dirs, files in os.walk(path):
        pass
    

    以下方法只是字符串处理,不管是否真存在该路径

    • os.path.join(path1,path2,...)
      可传入多个路径进行拼接,Linux/Unix/Mac使用/,Windows使用\作为分隔符
    import os
    os.path.join('/Users/michael', 'testdir')
    '/Users/michael/testdir'
    
    • os.path.split(path)
      将文件路径拆分为目录文件名组成的元组
    • os.path.splitext(path)
      将文件路径拆分为目录+不带扩展的文件名扩展名组成的元组
    os.path.splitext('/path/to/file.txt')
    ('/path/to/file', '.txt')
    
    新增/删除/改名
    # 创建目录
    os.mkdir('/Users/testdir')
    os.makedirs('/Users/testdir/a/b/c')#创建多级目录
    # 删除空目录
    os.rmdir('/Users/testdir/a/b/c')
    os.removedirs('/Users/a/b/c')#删除多级空目录
    # 重命名目录/文件:
    os.rename('test.txt', 'test.py')
    # 删除文件:
    os.remove('test.py')
    

    file-like Object

    拥有read方法的对象均可视为file-like Object,如open打开的文件、StringIO对象、BytesIO对象、满足条件的自定义对象

    class FLO():
        content = ""
        def read(self):
            return self.content
        def write(self, e):
            self.content += e
    

    序列化

    我们把变量从内存中变成可存储或传输的过程称之为序列化,序列化之后的内容才可以写入磁盘,或者通过网络传输到别的机器上。
    反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

    pickle

    pickle模块只能用于Python,并且可能不同版本的Python彼此都不兼容,因此不推荐使用

    json
    JSON类型 Python类型
    {} dict
    [] list
    "string" str
    1234.56 int或float
    true/false True/False
    null None

    通过json.dumps可将以上Python类型转为json字符串并返回,或通过json.dump将其写入一个 file-like Object。

    import json
    d = dict(name='Bob', age=20, score=88)
    myJson = json.dumps(d)
    print(myJson)#{"name": "Bob", "age": 20, "score": 88}
    
    with open("1.txt", "w+") as f:
        json.dump(d, f)
        f.seek(0)
        print(f.read())#{"name": "Bob", "age": 20, "score": 88}
    
    class FLO():
        content = ""
        def read(self):
            return self.content
        def write(self, e):
            self.content += e
    flo = FLO()
    json.dump(d, flo)
    print(flo.read())#{"name": "Bob", "age": 20, "score": 88}
    

    通过json.loads把JSON反序列化为Python对象并返回,或通过json.load从file-like Object中读取字符串并反序列化:

    json_str = '{"age": 20, "score": 88, "name": "Bob"}'
    print(json.loads(json_str))#{"name": "Bob", "age": 20, "score": 88}
    
    with open("1.txt", "r") as f:
        print(json.load(f))#{"name": "Bob", "age": 20, "score": 88}
    
    class FLO():
        content = ""
        def read(self):
            return self.content
        def write(self, e):
            self.content += e
    flo = FLO()
    flo.content = '{"name": "Bob", "age": 20, "score": 88}'
    print(json.load(flo))#{"name": "Bob", "age": 20, "score": 88}
    

    对于不包含在上述列表中的对象(如自定义类的实例),可以在序列化时配置default或在反序列化时配置object_hook,先转化为dict再通过该配置的函数转化为目标

    json.dumps(s, default=lambda obj: obj.__dict__)
    

    相关文章

      网友评论

          本文标题:Python 系统、IO、序列化

          本文链接:https://www.haomeiwen.com/subject/gfudnctx.html