前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python3 IO编程

Python3 IO编程

作者头像
嵌入式视觉
发布2022-09-05 14:17:41
4970
发布2022-09-05 14:17:41
举报
文章被收录于专栏:嵌入式视觉

Contents

Python IO编程值得是经常涉及到文件处理和操作得各种方法得应用,本文是学习笔记,主要参考廖雪峰《Python3教程》和部分网络学习资源。

IO 在计算机中指 Input/Output,也就是输入和输出。由于程序和运行时数据是在内存中驻留,由 CPU 这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘、网络等,就需要 IO 接口。 IO 编程简单理解指的是你的程序涉及到 cpu、内存和磁盘、网络的数据交互。因为 cpu、内存和磁盘、网络的速度有差异,所以在 IO 编程中,就存在速度严重不匹配的问题,比如网络爬虫的实例,网页解析可能只要 0.001秒,但是下载网页可能要 0.1s,为解决速度不匹配的问题,可以使用异步 IO,使用异步 IO 来编写程序性能会远远高于同步 IO,但是异步 IO的缺点是编程模型复杂。 操作 IO 的能力都是由操作系统提供的,每一种编程语言都会把操作系统提供的低级 C 接口封装起来方便使用, Python 也不例外。

文件读写

文件读写是最常见的 IO 操作。 Python 内置了读写文件的函数,用法和C 是兼容的。读写文件前,我们清楚,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。(来源,《Python3教程》-廖雪峰)

读文件

(来源见这里)

Python 读取文件的一般“标准做法“是,首先使用 with open(fine_name) 上下文管理器的方式打开一个文件并获得文件对象,然后使用 for 循环迭代它,逐行获取文件里的内容,如果该文件无法被打开,会抛出 OSError。用法示例如下:

代码语言:javascript
复制
  try:
    with open(demo.txt, 'r') as f:
      lines = f.readlines()
      for idx ,line in enumerate(lines):
          print(line)  # 循环打印demo.txt的每一行内容
  except Exception as e:
    print(e)
    print(traceback.print_exc())

file 对象使用 open 函数创建,file 对象的常用函数如下:

  • file.readline() 可以每次读取一行内容,包括 “\n” 字符(f 指的是文件对象)。
  • file.readlines() 一次读取所有内容并按行返回 list,行字符串末尾也包含了换行符 “\n”,可用 strip(“\n”) 方法去除。
  • file.read(chunk_size) 返回从当前位置往后读取 chunk_size 大小的文件内容 。
  • file.read() 可以一次读取文件的全部内容到内存中,用一个 str 对象表示。

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

如果文件很小, read() 一次性读取最方便;如果不能确定文件大小,反复调用 read(size) 比较保险;如果是配置文件,调用 readlines()最方便。

file-like Object

像 open() 函数返回的这种有个 read() 方法的对象,在 Python 中统称为 file-like Object。除了 file 外,还可以是内存的字节流,网络流,自定义流等等。file-like Object 不要求从特定类继承,只要写个 read() 方法就行。

写文件

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

代码示例如下:

代码语言:javascript
复制
with open(txt_fpath, 'w') as f:
    # start write str sequence
      f2.writelines(line2s)
  • f.write(str):将字符串写入文件,返回的是写入的字符长度。
  • f.writelines(sequence):向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符。

总结

open() 函数完整的语法格式如下:

代码语言:javascript
复制
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

在 Python 中,文件的读写都是通过 open() 方法实现的,区别在于 mode 参数不同。在 Python 中,文件的读写都是通过 open() 方法实现的,区别在于 mode 参数不同;使用 open() 方法一定要保证关闭文件对象,即调用 close() 方法。

操作文件和目录

在 Python 中,操作文件和目录的函数一部分放在 os 模块中,一部分放在 os.path 中。os 模块是操作系统接口模块,该模块提供了一些方便使用操作系统相关功能的函数。 如果想读写一个文件,请参阅 open() 函数,如果你想操作路径,请参阅 os.path 模块,如果你想在命令行上读取所有文件中的所有行请参阅 fileinput 模块。 有关创建临时文件和目录的方法,请参阅 tempfile 模块,对于高级文件目录处理,请参阅 shutil 模块。

os.path 模块常用函数

os.path 模块主要用于获取文件的属性,os.path 模块的函数都仅接受(Unicode)字节或字符串对象(路径)作为其参数。如果返回路径或文件名,则结果是相同类型的对象。os.path 模块的几种常用函数如下,这些函数的灵活应用需要自己在涉及操作文件/目录中的实例中灵活应用和总结。

  • os.getcwd() 返回当前工作目录
  • os.path.realpath(path) 返回 path 的真实路径
  • os.path.abspath(path) 返回 path 的绝对路径
    • os.path.abspath(os.path.join(os.getcwd(), "..")) 返回当前目录的上一级目录的绝对路径
    • os.path.abspath(os.path.join(os.getcwd(), "../../")) 返回当前目录的上上级目录的绝对路径
  • os.path.basename(path) 返回文件名
  • os.path.splitext(filename) 返回文件路径和文件后缀分割后的字符串元组

实例代码如下:

代码语言:javascript
复制
import os
print(os.getcwd().replace('\\\\', '/'))
print(os.listdir('./'))  # 列出当前目录下的所有子目录和文件名
os.path.abspath('./opencv_demo.py')
print(os.path.realpath('./').replace('\\', '/'))
print(os.path.abspath('../').replace('\\', '/'))
# 当path存在软链接时,两者有所区别,其他时候无区别
# os.path.realpath 会返回指定文件的标准路径,而非软链接所在的路径

程序输出如下:

C:/Users/zhanghonggao/Documents/image_utils/tools [‘.ipynb_checkpoints’, ‘crawl_images.py’, ‘daily_experiment.py’, ‘demo-image-classification-fastai’, ‘image_process.ipynb’, ‘input_nums.py’, ‘opencv_demo.py’, ‘pyqt5_demo.py’, ‘python3_practice.py’] C:/Users/zhanghonggao/Documents/image_utils/tools C:/Users/zhanghonggao/Documents/image_utils

os.path.exists() 和 os.path.isdir()、os.path.isfile() 等函数

  • os.path.exists(path) 方法可以直接判断文件/文件夹是否存在,功能相当于 os.path.isdir()、os.path.isfile() 的集合
  • os.path.isfile(path) 判断指定对象是否为文件。是返回 True,否则 False。
  • os.path.isdir(path) 判断指定对象是否为目录(文件夹)。是返回 True,否则 False。
  • os.path.islink(path) 判断路径是否为链接

os.path.basename 和 os.path.dirname 函数

  • os.path.basename(path)去掉目录路径,返回文件名
  • os.path.dirname(path)去掉文件名,返回目录路径

os.path.split() 和 os.path.splitext() 函数

  • os.path.split(path)返回( dirname(), basename())元组,basename是文件名(basename)
  • os.path.splitext(path)返回 (filename, extension) 元组,extension是文件后缀

os.path.getmtime() 和 os.path.getctime() 函数

  • os.path.getmtime(path) 返回最近文件修改时间
  • os.path.getctime(path) 返回 path 创建时间(windows系统),返回值是一个数,为纪元秒数(参考 time 模块)。如果该文件不存在或不可访问,则抛出 OSError 异常。

os.mkdir 和 os.makedirs 函数

代码语言:javascript
复制
path = '/test/path_01/path_02/path03/'
  • os.mkdir 函数只会创建 path 路径的最后一级目录
  • os.makedirs 函数递归地创建多层目录,如果 path 的四级目录都没有,则会自动递归创建全部 test、path_01、path_02、path_03 这 4 个目录

os.walk() 和 os.path.getsize() 函数

  • os.path.getsize(path) 返回文件大小,如果文件不存在就返回错误
  • os.walk(top, topdown=True, onerror=None, followlinks=False) 创建一个生成器,用以生成所要查找的目录及其子目录下的所有文件。

os.walk 函数可以得到一个三元tupple(dirpath, dirnames, filenames) generator,可 for 循环遍历这个 generaor,得到所有目录(包括子目录)的三元 tupletuple 第一个元素为起始路径,第二个为起始路径下的文件夹,第三个是起始路径下的文件。

  • dirpath 是一个 string,代表目录的路径。(文件夹路径)
  • dirnames 是一个 list,包含了 dirpath 下所有子目录的名字。(文件夹名字)
  • filenames 是一个 list,包含了非目录文件的名字。(文件名)

os.walk(root_dir) 先遍历 root_dir 目录下的第一个子目录,再依次遍历第二、第三、第 n 个目录,每遍历一个子目录都得到一个 generator。实例代码: python 获取文件夹大小。

代码语言:javascript
复制
"""python 获取指定文件夹大小"""
import os
f_dir = os.path.abspath(os.path.dirname(__file__))
def get_dir_size(dir):
    size = 0
    for root, dirs, files in os.walk(dir):
        size += sum([os.path.getsize(os.path.join(root, name)) for name in files])
    return size
if __name__ == '__main__':
    size = get_dir_size('../')
    print('Total size is: %.3f Mb'%(size/1024/1024))

序列化

我们把变量从内存中变成可存储或传输的过程称之为序列化,在 Python中叫 pickling,在其他语言中也被称之为 serialization, marshalling,flattening 等等,都是一个意思。反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即 unpickling。  Python中提供了pickle模块实现对象的序列化,常用方法如下:

  • pickle.dumps()方法把任意对象序列化成一个 bytes,然后,就可以把这个 bytes 写入文件
  • pickle.dump()方法直接把对象序列化后写入一个 file-like Object
  • pickle.loads()方法用于从bytes中反序列化出对象
  • pickle.load()方法从一个 file-like Object 中直接反序列化出对象,

**这些方法的应用,建议到实际工程代码中去练习,才能理解和灵活应用**。实例代码如下:

代码语言:javascript
复制
import pickle
d = dict(name='Bob', age=20, score=88)
with open('demo.txt', 'wb') as f:
    pickle.dump(d, f)
with open('demo.txt', 'rb') as f:
    d = pickle.load(f)
print(d)

程序输出如下:

{‘name’: ‘Bob’, ‘age’: 20, ‘score’: 88}

Json

  • json.loads()、 json.dumps()函数适用于json格式的字符串对象
  • json.load()、json.dump()函数适用于json文件,

dumps()方法返回一个 str,内容就是标准的 JSON。类似的, dump()方法可以直接把 JSON 写入一个 file-like Object。  要把 JSON 反序列化为 Python 对象,用 loads()或者对应的 load()方法,前者把 JSON 的字符串反序列化,后者从 file-like Object 中读取字符串并反序列化

JSON 表示的对象就是标准的 JavaScript 语言的对象, JSON 和 Python内置的数据类型对应如下:

总结

Python官方的对象序列化模块是pickle,实际工程中发现使用pickle文件反序列化出对象速度更快,但如果要把序列化搞得更通用、更符合 Web 标准,建议使用 json 模块。

参考资料

《Python教程-廖雪峰》 Python 工匠:高效操作文件的三个建议

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-04-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文件读写
    • 读文件
      • file-like Object
        • 写文件
          • 总结
          • 操作文件和目录
            • os.path 模块常用函数
              • os.path.exists() 和 os.path.isdir()、os.path.isfile() 等函数
                • os.path.basename 和 os.path.dirname 函数
                  • os.path.split() 和 os.path.splitext() 函数
                    • os.path.getmtime() 和 os.path.getctime() 函数
                      • os.mkdir 和 os.makedirs 函数
                        • os.walk() 和 os.path.getsize() 函数
                        • 序列化
                          • Json
                            • 总结
                            • 参考资料
                            相关产品与服务
                            文件存储
                            文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档