cook book:文件与IO+数据编码和处理
作者:互联网
1:读写文本数据 :读写各种不同编码的文本数据ASCII,UTF-8或UTF-16编码等
# rt模式下,python在读取文本时会自动把\r\n转换成\n,文本文件用二进制读取用‘rt’; # 使用带有 rt 模式的 open() 函数读取文本文件 with open('aaaa', "rt") as f: data = f.read() print(data, type(data)) 输出aaaa文件读取出来的数据,\r\n都转换成\n,读取出来的数据是字符串str类型 with open('aaaa', "rt") as f: for line in f: print(line)
# 写入一个文本文件,使用带有 wt 模式的 open() 函数, 如果之前文件内容存在则清除并覆盖掉。 # 编写文本数据块 with open('somefile.txt', 'wt') as f: f.write(text1) f.write(text2) ... # 重定向打印语句 with open('somefile.txt', 'wt') as f: print(line1, file=f) print(line2, file=f) ...
# 已存在文件中添加内容,使用模式为 at 的 open() 函数。 # 文件的读写操作默认使用系统编码,可以通过调用 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编码读取一个文件的时候也许不能产生完全正确的文本解码数据,
但是它也能从中提取出足够多的有用数据。同时,如果你之后将数据回写回去,原先的数据还是会保留的
# with语句 # with语句给被使用到的文件创建了一个上下文环境, 但 with 控制块结束时,文件会自动关闭。你也可以不使用 with 语句,但是这时候你就必须记得手动关闭文件 f = open('somefile.txt', 'rt') data = f.read() f.close() # 换行符的识别Unix和Windows中是不一样,分别是 \n 和 \r\n # 默认情况下,Python会以统一模式处理换行符。 这种模式下,在读取文本的时候,
Python可以识别所有的普通换行符并将其转换为单个 \n 字符。 类似的,在输出时会将换行符 \n 转换为系统默认的换行符。
如果你不希望这种默认的处理方式,可以给 open() 函数传入参数 newline='' ,
with open('somefile.txt', 'rt', newline='') as f:
# 在Unix机器上面读取一个Windows上面的文本文件 内容是 hello world!\r\n >>> # 已启用换行转换(默认) >>> f = open('hello.txt', 'rt') >>> f.read() 'hello world!\n' >>> # 新行翻译已禁用 >>> g = open('hello.txt', 'rt', newline='') >>> g.read() 'hello world!\r\n' >>>
# 读取文件编码错误问题,读取或者写入一个文本文件时,你可能会遇到一个编码或者解码错误 >>> f = open('sample.txt', 'rt', encoding='ascii') >>> f.read() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/lib/python3.3/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 12: ordinal not in range(128) >>> 这种错误通常表示你读取文本时指定的编码不正确, # 仔细阅读说明并确认你的文件编码是正确的(比如使用UTF-8而不是Latin-1编码或其他)。
如果编码错误还是存在的话,你可以给 open() 函数传递一个可选的 errors 参数来处理这些错误。 下面是一些处理常见错误的方法 >>> # 用Unicode U+fffd替换字符替换坏字符 >>> f = open('sample.txt', 'rt', encoding='ascii', errors='replace') >>> f.read() 'Spicy Jalape?o!' >>> # 完全忽略坏字符 >>> g = open('sample.txt', 'rt', encoding='ascii', errors='ignore') >>> g.read() 'Spicy Jalapeo!' >>> # 对于文本处理的首要原则是确保你总是使用的是正确编码。当模棱两可的时候,就使用默认的设置(通常都是UTF-8)
2:打印输出至文件中 将 print()
函数的输出重定向到一个文件中去 ——>在 print()
函数中指定 file
关键字参数
with open('d:/work/test.txt', 'wt') as f: print('Hello World!', file=f)
文件必须是以文本模式打开。 如果文件是二进制模式的话,打印就会出错
3:使用其他分隔符或行终止符打印 使用 print()
函数输出数据,改变默认的分隔符或者行尾符
# print() 函数中使用 sep 和 end 关键字参数,改变输出方式 print('ACME', 50, 91.5) # ACME 50 91.5 print('ACME', 50, 91.5, sep=',') # ACME,50,91.5 print('ACME', 50, 91.5, sep=',', end='!!\n') # ACME,50,91.5!! # end 参数可以在输出中禁止换行 for i in range(5): print(i, end=' ') # str.join和sep最后输出一样 print(','.join(('ACME', '50', '91.5'))) print('ACME', 50, 91.5, sep=',') # str.join() 的问题在于它仅仅适用于字符串 row = ('ACME', 50, 91.5) print(','.join(row)) # 报错join里面的参数需要每个都是字符串 print(','.join(str(x) for x in row)) # 需要这样写 # 直接使用sep参数也可以 row = ('ACME', 50, 91.5) print(*row, sep=',')
4:读写字节数据 读写二进制文件,比如图片,声音文件等, 使用rb
或 wb
的 open()
函数来读取或写入二进制数据
# rb 或 wb 的 open() 函数来读取或写入二进制数据 # 以单字节字符串的形式读取整个文件 with open('somefile.bin', 'rb') as f: data = f.read() # 将二进制数据写入文件 with open('somefile.bin', 'wb') as f: f.write(b'Hello World') # 读取二进制数据时,需要指明的是所有返回的数据都是字节字符串格式的,而不是文本字符串。 # 在写入的时候,必须保证参数是以字节形式对外暴露数据的对象(比如字节字符串,字节数组对象等)
# 读取二进制数据的时候,字节字符串和文本字符串的语义差异可能会导致一个潜在的陷阱,索引和迭代动作返回的是字节的值而不是字节字符串 t = 'Hello World' print(t[0]) # H b = b'Hello World' print(b[0]) # 72 返回的是字节H的十进制的值72,不是返回的b'H'这个字节
# 从二进制模式的文件中读取或写入文本数据,必须确保要进行解码和编码操作 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')) decode解码,encode编码
# 二进制I/O还有一个鲜为人知的特性就是数组和C结构体类型能直接被写入,而不需要中间转换为自己对象 import array nums = array.array('i', [1, 2, 3, 4]) with open('data.bin','wb') as f: f.write(nums)
# 这个把数组对象写入文本,可以直接写入这个数组对象,并不是写入一个字符串 # 这个适用于任何实现了被称之为”缓冲接口”的对象,这种对象会直接暴露其底层的内存缓冲区给能处理它的操作。 二进制数据的写入就是这类操作之一 # 很多对象还允许通过使用文件对象的 readinto() 方法直接读取二进制数据到其底层的内存中去 >>> import array # array是数组,这个数组里面只能放数字 >>> a = array.array('i', [0, 0, 0, 0, 0, 0, 0, 0]) >>> with open('data.bin', 'rb') as f: ... f.readinto(a) # 从f文件句柄中读取数据后放到a这个容器中,所以返回[1, 2, 3, 4, 0, 0, 0, 0] ... 16 >>> a array('i', [1, 2, 3, 4, 0, 0, 0, 0]) >>>
# mmap,内存映射文件,文件data.bin可以放字符串 import mmap a = mmap.mmap(-1, 20) with open('data.bin', 'rb') as f: f.readinto(a) print(a.read())
标签:rt,数据编码,读取,编码,book,文件,IO,print,open 来源: https://www.cnblogs.com/yuanwt93/p/15109405.html