python io简单总结

Python——IO编程 IO在计算机中指Input/Output,也就是输入和输出。由于程序和运行时数据是在内存中驻留,由CPU这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘、网络等,就需要IO接口。比如你打开浏览器,访问新浪首页,浏览器这个程序就需要通过网络IO获取新浪的网页。浏览器首先会发送数据给新浪服务器,告诉它我想要首页的HTML,这个动作是往外发数据,叫Output,随后新浪服务器把网页发过来,这个动作是从外面接收数据,叫Input。所以,通常,程序完成IO操作会有Input和Output两个数据流。 阅读详情

1、文件的读写操作默认使用系统编码,可以通过调用 sys.getdefaultencoding() 来得到。在大多数机器上面都是 utf-8 编码。如果你已经知道你要读写的文本是其他编码方式,那么可以通过传递一个可选的 encoding 参数给 open()

with open('somefile.txt', 'rt', encoding='latin-1') as f:
	...

Python 支持非常多的文本编码。几个常见的编码是 ascii, latin-1, utf-8 和 utf-16。在 web 应用程序中通常都使用的是 UTF-8。ascii 对应从 U+0000 到 U+007F 范围内的 7 位字符。latin-1 是字节 0-255 到 U+0000 至 U+00FF 范围内 Unicode 字符的直接映射。当读取一个未知编码的文本时使用 latin-1 编码永远不会产生解码错误。使用latin-1 编码读取一个文件的时候也许不能产生完全正确的文本解码数据,但是它也能从中提取出足够多的有用数据。同时,如果你之后将数据回写回去,原先的数据还是会保留的。

2、模式:

t   是windows平台特有的所谓text mode(文本模式),区别在于会自动识别windows平台的换行符
rt  模式下,python在读取文本时会自动把\r\n转换成\n

打印输出至文件中, 你想将 print() 函数的输出重定向到一个文件中去(关于输出重定向到文件中就这些了。但是有一点要注意的就是文件必须是以文本模式打开。如果文件是二进制模式的话,打印就会出错。)

with open('d:/work/test.txt', 'wt') as f:
	print('Hello World!', file=f)

3、在读取二进制数据的时候,字节字符串和文本字符串的语义差异可能会导致一个潜在的陷阱。特别需要注意的是,索引和迭代动作返回的是字节的值而不是字节字符串。

t = 'Hello World'
print(t[0])

b = b'Hello World'
print(b[0])

如果你想从二进制模式的文件中读取或写入文本数据,必须确保要进行解码和编码操作。比如:

with open('somefile.bin', 'rb') as f:
	data = f.read(16)
	text = data.decode('utf-8')

with open('somefile.bin', 'wb') as f:
	text = 'Hello World'
	f.write(text.encode('utf-8'))

二进制 I/O 还有一个鲜为人知的特性就是数组和 C 结构体类型能直接被写入,而不需要中间转换为自己对象。

nums = array.array('i', [1, 2, 3, 4])
with open('data.bin', 'wb') as f:
    f.write(nums)

这个适用于任何实现了被称之为” 缓冲接口” 的对象,这种对象会直接暴露其底层的内存缓冲区给能处理它的操作。二进制数据的写入就是这类操作之一。
很多对象还允许通过使用文件对象的 readinto() 方法直接读取二进制数据到其底层的内存中去。比如:

a = array.array('i', [0, 0, 0, 0, 0, 0, 0, 0])
with open('data.bin', 'rb') as f:
    f.readinto(a)

print(a)

但是使用这种技术的时候需要格外小心,因为它通常具有平台相关性,并且可能会依赖字长和字节顺序 (高位优先和低位优先)

你想直接读取二进制数据到一个可变缓冲区中,而不需要做任何的中间复制操作。或者你想原地修改数据并将它写回到一个文件中去。

def read_into_buffer(filename):
    buf = bytearray(os.path.getsize(filename))
    with open(filename, 'rb') as f:
        f.readinto(buf)
    return buf


with open('sample.bin', 'wb') as f:
    f.write(b'Hello World')

buf = read_into_buffer('sample.bin')
print(buf)

with open('newsample.bin', 'wb') as f:
    f.write(buf)

文件对象的 readinto() 方法能被用来为预先分配内存的数组填充数据,甚至包括由 array 模块或 numpy 库创建的数组。和普通 read() 方法不同的是, readinto() 填充已存在的缓冲区而不是为新对象重新分配内存再返回它们。因此,你可以使用它来避免大量的内存分配操作。比如,如果你读取一个由相同大小的记录组成的二进制文件时,你可以像下面这样写:

record_size = 32 # Size of each record (adjust value)
buf = bytearray(record_size)
with open('somefile.bin', 'rb') as f:
	while True:
		n = f.readinto(buf)
		if n < record_size:
			break
		# Use the contents of buf
		

另外有一个有趣特性就是 memoryview ,它可以通过零复制的方式对已存在的缓冲区执行切片操作,甚至还能修改它的内容。比如:

def read_into_buffer(filename):
    buf = bytearray(os.path.getsize(filename))
    with open(filename, 'rb') as f:
        f.readinto(buf)
    return buf


with open('sample.bin', 'wb') as f:
    f.write(b'Hello World')

buf = read_into_buffer('sample.bin')
print(buf)

m1 = memoryview(buf)
m2 = m1[-5:]
print(m2)
m2[:] = b'WORLD'
print(buf)

使用 f.readinto() 时需要注意的是,你必须检查它的返回值,也就是实际读取的字节数。如果字节数小于缓冲区大小,表明数据被截断或者被破坏了 (比如你期望每次读取指定数量的字节)。

4、读写压缩文件
读写一个 gzip 或 bz2 格式的压缩文件
gzip 和 bz2 模块可以很容易的处理这些文件。两个模块都为 open() 函数提供了另外的实现来解决这个问题。比如,为了以文本形式读取压缩文件。

with gzip.open('somefile.gz', 'wt') as f:
    f.write('Hello World')


with gzip.open('somefile.gz', 'rt') as f:
    text = f.read()

print(text)

with bz2.open('somefile.bz2', 'wt') as f:
    f.write(text)

with bz2.open('somefile.bz2', 'rt') as f:
    text = f.read()
print(text)

如上,所有的 I/O 操作都使用文本模式并执行 Unicode 的编码/解码。类似的,如果你想操作二进制数据,使用 rb 或者 wb 文件模式即可

大部分情况下读写压缩数据都是很简单的。但是要注意的是选择一个正确的文件模式是非常重要的。如果你不指定模式,那么默认的就是二进制模式,如果这时候程序想要接受的是文本数据,那么就会出错。 gzip.open() 和 bz2.open() 接受跟内置的open() 函数一样的参数,包括 encoding,errors,newline 等等。
当写入压缩数据时,可以使用 compresslevel 这个可选的关键字参数来指定一个压缩级别。比如:

with gzip.open('somefile.gz', 'wt', compresslevel=5) as f:
	f.write(text)
	

默认的等级是 9,也是最高的压缩等级。等级越低性能越好,但是数据压缩程度也越低。

最后一点, gzip.open() 和 bz2.open() 还有一个很少被知道的特性,它们可以作用在一个已存在并以二进制模式打开的文件上。比如,下面代码是可行的:

import gzip


f = open('somefile.gz', 'rb')

with gzip.open(f, 'rt') as g:
	text = g.read()
	

这样就允许 gzip 和 bz2 模块可以工作在许多类文件对象上,比如套接字,管道和内存中文件等。

5、你想在一个固定长度记录或者数据块的集合上迭代,而不是在一个文件中一行一行的迭代。可以使用 iter 和 functools.partial()

from functools import partial

RECORD_SIZE = 32
with open('somefile.data', 'rb') as f:
    records = iter(partial(f.read, RECORD_SIZE), b'')
    for r in records:
        print(r)

这个例子中的 records 对象是一个可迭代对象,它会不断的产生固定大小的数据块,直到文件末尾。要注意的是如果总记录大小不是块大小的整数倍的话,最后一个返回元素的字节数会比期望值少。

iter() 函数有一个鲜为人知的特性就是,如果你给它传递一个可调用对象和一个标记值,它会创建一个迭代器。这个迭代器会一直调用传入的可调用对象直到它返回标记值为止,这时候迭代终止。

在例子中, functools.partial 用来创建一个每次被调用时从文件中读取固定数目字节的可调用对象。标记值 b’’ 就是当到达文件结尾时的返回值。

最后再提一点,上面的例子中的文件时以二进制模式打开的。如果是读取固定大小的记录,这通常是最普遍的情况。而对于文本文件,一行一行的读取 (默认的迭代行为) 更普遍点。

6、内存映射的二进制文件
你想内存映射一个二进制文件到一个可变字节数组中,目的可能是为了随机访问它的内容或者是原地做些修改。
使用 mmap 模块来内存映射文件。下面是一个工具函数,向你演示了如何打开一个文件并以一种便捷方式内存映射这个文件。

def memory_map(filename, access=mmap.ACCESS_WRITE):
    size = os.path.getsize(filename)
    fd = os.open(filename, os.O_RDWR)
    return mmap.mmap(fd, size, access=access)


size_data = 1000000
with open('data', 'wb') as f:
    f.seek(size_data - 1)
    f.write(b'\x00')


m = memory_map('data')
print(len(m),  m[0])
m[0:11] = b'Hello World'

with open('data', 'rb') as f:
    print(f.read(11))
    

mmap() 返回的 mmap 对象同样也可以作为一个上下文管理器来使用,这时候底层的文件会被自动关闭。比如

with memory_map('data') as m:
	print(len(m))
	print(m[0:10])

默认情况下, memeory map() 函数打开的文件同时支持读和写操作。任何的修改内容都会复制回原来的文件中。如果需要只读的访问模式,可以给参数 access 赋值为mmap.ACCESS READ 。比如:

m = memory_map(filename, mmap.ACCESS_READ)

如果你想在本地修改数据,但是又不想将修改写回到原始文件中,可以使用mmap.ACCESS COPY :

m = memory_map(filename, mmap.ACCESS_COPY)

为了随机访问文件的内容,使用 mmap 将文件映射到内存中是一个高效和优雅的方法。例如,你无需打开一个文件并执行大量的 seek() , read() , write() 调用,只需要简单的映射文件并使用切片操作访问数据即可。
一般来讲, mmap() 所暴露的内存看上去就是一个二进制数组对象。但是,你可以使用一个内存视图来解析其中的数据。比如:

m = memory_map('data')
# Memoryview of unsigned integers
v = memoryview(m).cast('I')
v[0] = 7
print(m[0:4])
 

需要强调的一点是,内存映射一个文件并不会导致整个文件被读取到内存中。也就是说,文件并没有被复制到内存缓存或数组中。相反,操作系统仅仅为文件内容保留了一段虚拟内存。当你访问文件的不同区域时,这些区域的内容才根据需要被读取并
映射到内存区域中。而那些从没被访问到的部分还是留在磁盘上。所有这些过程是透明的,在幕后完成!

如果多个 Python 解释器内存映射同一个文件,得到的 mmap 对象能够被用来在解释器直接交换数据。也就是说,所有解释器都能同时读写数据,并且其中一个解释器所做的修改会自动呈现在其他解释器中。很明显,这里需要考虑同步的问题。但是这种方法有时候可以用来在管道或套接字间传递数据。

要注意的是使用 mmap() 函数时会在底层有一些平台的差异性。另外,还有一些选项可以用来创建匿名的内存映射区域。参考:https://docs.python.org/3/library/mmap.html

python IO模型 一、事件驱动模型 1)传统的编程是如下线性模式的: 开始---&gt;代码块A---&gt;代码块B---&gt;代码块C---&gt;代码块D---&gt;......---&gt;结束 每一个代码块里是完成各种各样事情的代码,但编程者知道代码块A,B,C,D...的执行顺序,唯一能够改变这个流程的是数据。输入不同的数据,根据条件语句判断,流程或许就改为A---&gt;C---&gt;E.... 阅读详情

相关推荐

Python - io 模块

文章目录关于 io 模块1、文本 I/O2、二进制(字节) I/O3、原始 I/O二、文本编码格式选择性的 EncodingWarning三、高阶模块接口四、类的层次结构1、I/O 基类class `io.IOBase`class `io.RawIOBase`class `io.BufferedIOBase`2、原始文件 I/Oclass `io.FileIO`3、缓冲流class `io.BytesIO`class `io.BufferedReader`class `io.BufferedWriter`c

AI工程化、开源分享、文档翻译、代码笔记 5136

Python中s.recv(bufsize[,flag])的bufsize的大小

当使用socket模块,在接收请求数据时一般用s.recv()函数。这个函数有一个bufsize参数,指定要接受的最大数据量。一般教程会推荐设定这个值为1024。如这个简单的服务器代码: ```python import socket host = '127.0.0.1' port = 8080 web = socket.socket() web.bind((host, port)) web.l...

momod的博客 4751

scanpy单细胞转录组python教程(四):单样本数据分析之降维聚类及细胞注释

本文介绍了使用scanpy进行单细胞转录组分析的降维聚类和细胞注释流程。首先通过PCA降维并可视化主成分贡献,然后使用不同分辨率参数(0.2-1.0)进行Leiden聚类。通过Wilcoxon检验鉴定marker基因,并基于经典marker基因手动注释细胞类型。最后对低质量细胞群进行过滤,并重新计算邻居图和UMAP可视化。流程中包含PCA方差分析、多分辨率聚类比较、marker基因筛选和基于UMAP的细胞类型可视化等关键步骤,为后续分析奠定基础。

qq_42090739的博客 943

python 读取二进制数据到可变缓冲区中

想直接读取二进制数据到一个可变缓冲区中,而不需要做任何的中间复制操作。或者你想原地修改数据并将它写回到一个文件中去。 为了读取数据到一个可变数组中,使用文件对象的readinto() 方法。比如 import os.path def read_into_buffer(filename): buf = bytearray(os.path.getsize(filename)) with ...

weixin_34290096的博客 525

火山引擎大模型语音合成双向流式API实战:Python实现与优化指南

本文详细介绍了如何利用火山引擎大模型语音合成双向流式API,通过Python实现低延迟、实时的语音合成应用。文章从核心协议解析入手,提供了完整的Python客户端实现代码,并分享了连接复用、错误重试、与LLM流式输出集成等实战优化技巧,帮助开发者快速构建智能客服、实时语音助手等AI应用。

n8m7b6v5c4的博客 1219

pi-star图形界面安装指南

pi-star图形界面安装指南,MMDVM热点安装,树莓派3B+热点

blueisman的专栏 1909

python中buffer类型的读取

在使用sqlite3存取二进制数据的时候,使用buffer对数据进行转化,可以将数据存入相应的Blob类型中。但是在读取的时候遇到了问题,如图: 这种方式下存入的是只读地址,那怎么读取之前存进去的内容呢?只需要用str强制转换就可以了,如下图: ...

sailor5976的博客 1万+

Matcap与菲涅尔

菲尼尔效果(简化版公式):fresnel = base + scale*((1-v*n)^power)透明队列为后前渲染,不关闭深度写入则会覆盖之前的像素,导致混合不了。y的值为0~1,根据x3返回对应y值。两色混合做个demo看看!混合为什么要关闭深度写入?

weixin_62773441的博客 372

python 处理protobuf数据示例

google protobuffer protocol buffers – a language-neutral, platform-neutral, extensible way of serializing structured data for use in communications protocols, data storage, and more. Protocol buffers...

SchopenhauerZhang的博客 6573

AI 编程新范式:一文彻底搞懂 LLM、Agent、MCP、Skill 是怎么协作的

本文用通俗易懂的方式解析了AI编程新架构的核心概念。通过"三国演义"类比,文章将复杂的技术架构拆解为:Agent(军师/大脑)负责思考和决策,Skill(招式/手脚)执行具体操作,MCP(令箭/协议)作为通信标准,MCP Server(将军/身体)承载多个Skill。这套分工架构使AI从单纯聊天进化成能完成实际编程任务的全能助手,实现了关注点分离——Agent专注智能提升,Skill专注功能实现,MCP确保稳定连接。这正是Cursor、Claude等新一代AI开发工具采用的核心架构,标志

猫老板的豆 3082

MGC3130 3D手势识别传感器原理图设计,已量产(交互传感器)

最近在落地一款互动艺术装置的控制模块,选了 Microchip 的 MGC3130 做核心 —— 这颗芯片算是 GestIC® 近场传感技术的 “熟面孔” 了,把 3D 手势识别、运动跟踪的信号处理都集成在一颗芯片里,0-10cm 的检测距离刚好适配桌面级互动场景,挥挥手就能控设备的体验,放在艺术装置里确实很出效果。今天扒一下实际跑通的原理图,聊聊每个模块的设计思路。

不脱发的程序猿 371

python IO(读取、写入文件内容)总结

1、打开桌面的一个txt文件,并显示里面的内容 # f = open(r'C:Users\TEST\Desktop\tmp2.txt','r',encoding='utf-8',errors='ignore') f = open('C:Users/TEST/Desktop/tmp2.txt','r',encoding='utf-8',errors='ignore') fr = f.read() p...

blackeagleoht的博客 3526

lammps案例:reaxff势模拟Fe(OH)3高温反应过程

所有的reaxff模拟,如:氧化、腐蚀、热裂解、燃烧等模拟,均可采用此模拟框架,只需要更换data文件、势文件,代码中的control文件可以不写,电荷平衡文件也可以用reaxff替换。该案例主要模拟Fe(OH)3在高温下的反应过程,主要代码来自lammps自带的案例。lammps自带案例没有产物输出,故在此基础上稍加修改,增加了产物输出命令。如果需要系统学习反应势的模拟,可考虑报名培训课程。本文分享一个reaxff反应势的案例。in文件代码已经注释,以供参考。大家好,我是小马老师。

lammps_jiayou的博客 1966

python的io模块

open函数是一个工厂函数。根据传入的变量,open函数会进行文件的开启、文件对象的创建与设定,然后返回文件对象。我们来看一下指定不同变量时,open函数具体为我们返回了什么类型的文件对象呢: >>> open('Documents/me.txt') <_io.TextIOWrapper name='Documents/me.txt' mode='r' encoding='cp936'> >>> open('Documents/me.txt','rb')

piglite的专栏 3073

点云目标检测:open3d多窗口联动可视化

多个模型之间的对比除了指标之外,还需要可以直接直观的对比可视化结果,这次介绍一下如何使用open3d同时打开两个窗口分别加载两个模型的结果进行对比,同时实现两个窗口的联动,也就是当一个窗口拖动或者缩放时另外一个窗口也跟着做同样的变换。

zhaoguanhua的博客 4688

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

python 异步io_Python中的异步IO:完整的演练

python 异步ioAsync IO is a concurrent programming design that has received dedicated support in Python, evolving rapidly from Python 3.4 through 3.7, and probably beyond. 异步IO是一种并发编程设计,已获得Python的专门支持,从...

cumei1658的博客 3036

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

深入浅出:Python IO编程

在Python中,类是创建对象的蓝图或模板。通过定义类可以规定对象应具有哪些属性和行为。使用class关键字来声明一个类,并且通常会有一个特殊的构造函数__init__()用于初始化新创建的对象。

软件架构师笔记 835

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

python io

总是看到关于io的要求,却一直不怎么理解io的具体含义,今天在这里做一下总结和解释。先解释一下io的具体含义: io模块提供了python用于处理各种类型I/O的主要工具,主要有三种类型的I/O:文本I/O,二进制I/O和原始I/O;这些都是通用类型,各种后备存储可使用其中的每一种类型,所以这些类型的具体对象称为文件对象。他通常的术语叫流和文件对象。 每个具体流对象都具有各种功能:可以是只读,...

学习python 2493

Python IO流

输入流中的open函数中的mode选择为“r”,表示为Read,输入流r:表示read,字符输入流rb:表示read binary,字节输入流输出流中的open函数中的mode选择为“w”,表示为Write,输出流w:表示write,字符输出流wb:表示write binary,字节输出流在 Python 中,标准输出流通常指的是sys.stdout,它是一个sys模块中的输出流对象,用于将文本数据输出到控制台。标准输出流是 Python 标准库中的一部分,提供了一种在控制台上输出信息的简单方式。

Fddadd的博客 1699

Python的io模块

io 模块提供了 Python 用于处理各种 I/O 类型的主要工具。三种主要的 I/O类型分别为: 文本 I/O, 二进制 I/O 和 原始 I/O。

1267

python异步io_Python 异步 IO

Python 异步 IO通常用异步 IO 用于服务器端的网络编程,但是磁盘文件的操作也是可以进行异步 IO 的,本文将会介绍怎么用 Python 进入异步读写文件。本文将使用 os.open 这个低层的 API 来实现异步 IO 的功能。open 与 os.open 的关系open 函数是对 os.open 函数的封装,如果想使用异步 IO 直接使用 os.open 就行。1、用 open 实现向...

weixin_39821718的博客 227

Python从入门到精通之IO模型

IO模型介绍 为了更好地了解IO模型,我们需要事先回顾下:同步、异步、阻塞、非阻塞 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出的答案都可能不同,比如wiki,就认为asynchronous IO和non-blocking IO是一个...

Dev-L的博客 2162

Python 中的 Async IO [异步 IO]

Async IO是一种并发编程设计,在Python中得到了专门的支持,从Python 3.4到3.7,并且可能还会继续发展。你可能会担心地想到:“并发、并行、线程、多进程。这已经够难理解的了。异步IO又是什么?本教程旨在帮助你回答这个问题,让你更好地理解Python中异步IO的方法。协程(特殊的生成器函数)是Python中异步IO的核心,我们将在后面详细介绍它们。注意:在本文中,我使用术语"异步IO(async IO)"表示异步IO的与语言无关的设计,而"asyncio"则是指Python的包。

szial的专栏 8241

Python 信号驱动式IO、异步IO、IO多路复用

这段代码是IO多路复用服务器的经典实现,能高效处理多个客户端的连接和数据收发。通过select和非阻塞IO,单进程即可实现高并发网络服务。说明通过监听所有socket的可读事件。新连接加入inputs,断开连接移除inputs。单进程即可高效管理多个客户端。信号驱动IO通过信号机制实现异步IO事件通知,主程序无需阻塞等待。需要注册信号处理函数、设置fd所有者和异步IO标志。适合底层高性能场景,Python中较少直接使用。说明需要底层操作系统支持,Python中很少直接用。

qq_37805832的博客 834
上一篇: io.StringIO() 和 io.BytesIO() 类来创建类文件对象操作字符串数据
下一篇: python functools.partial 减少某个函数的参数个数
MZP_man
博客等级 码龄8年 188粉丝 145原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值