1 Python文件IO操作

常用操作如下表:

clumncolumn
open打开
read读取
write写入
close关闭
readline行读取
readlines多行读取
seek文件指针操作
tell指针位置
1.1 open

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
示例

f = open('test')
print(f.read())
f.close()

文件操作中,最常用的就是读和写。
文件访问的模式有两种:文本模式和二进制模式。不同模式下,操作函数不尽相同,表现的结果也不一样。

open函数的参数

  • file 打开或者要创建的文件名,如果不指定路径,默认是当前路径
  • mode模式
模式描述
r 模式只读打开文件,如果使用write方法,则会抛出异常;如果文件不存在,抛出FileNotFoundError异常
w只写打开,如果读取则抛出异常;如果文件不存在,则直接创建文件;如果文件存在,则清空文件内容
x文件不存在,创建文件,并只写方式打开;文件存在,抛出FileExistsError异常
a文件存在,只写打开,追加内容;文件不存在,则创建后,只写打开,追加内容
r只读,wxa都是只写wxa都可以产生文件,w不管文件存在与否,都会生成全新内容的文件;a不管文件是否存在,都能在打开的文件尾部追加;x必须要求文件事先不存在,自己造一个文件。
文本模式t字符流,将文件的字节按照某种字符编码理解,按照字符操作。默认模式。
二进制模式b字节流,将文件按照字节理解,与字符编码无关。二进制模式操作时,字节操作使用bytes类型。
  • 文件指针

mode = r 指针起始在0
mode = a 指针起始在EOF(文件末尾)

  • seek(offset[,whence]) 移动指针. offset偏移多少字节。

文本模式下:
whence 0 缺省值,表示从头开始,只接受正整数
whence 1 表示从当前位置 ,只接受0
whence 2表示从EOF位置开始,只接受0

字节模式:
wence 0 缺省值,表示从头开始,offset只接受正整数
whence 1 表示从当前位置 ,offset可正可负
whence 2表示从EOF位置开始,offset可正可负

1.2 常用函数
函数说明
read(size=-1)默认读取所有,文本模式下为读取字符数量,字节模式下为字节数
readline(size=-1)一次读取多少行内容,默认所有
readlines读取多行内容
write(s)把字符串s写入到文件中,并返回字符的个数
close()flush并关闭文件对象,关闭后,再次关闭没有效果
1.3 其他函数
函数说明
seekable()是否可seek
readable()是否可读
writeabel()是否可写
closed()是否已经关闭

2 上下文管理

先看一个例子


lst = []
for _ in range(2000):
    lst.append(open("test"))
# OSError: [Errno 24] Too many open files:'test'
print(len(lst))

ulimit -a 查看所有限制,其中open files 就是打开的文件数限制,默认1024。

(base) zhaow@zhaow-610:~$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 62945
max locked memory       (kbytes, -l) 65536
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 62945
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

解决办法:
1.异常处理
当出现异常的时候,拦截异常,但是很多代码都可能出现OSError异常,还不好判断异常就是因为资源限制产生的。

f = open('test')
try:
    f.write('abc')
finally:
    f.close()

使用finally 可以保证所有文件可以被关闭。

上下文管理
一种特殊的语法,交给解释器去释放文件。

with open('test') as f:
    f.read()

使用with...as关键字:
上下文管理语句并不会开启新的作用域
with语句块执行完的时候,会自动关闭文件对象

对应类似文件对象的IO对象,一般来说都需要在使用完的时候关闭、注销,以释放资源。
IO被打开的时候,会获得的文件描述符fd,但计算机资源是有限的,所以操作系统都会做限制,目的是为了保护计算机资源不要被完全耗尽。
一般情况下,除非特别明确的知道资源情况,否则不要提高资源的限制来解决问题。

3.StingIO和BytesIO

  • StingIO

io模块中类: from io import StringIO
内存中,开辟的一个文本模式的buffer,可以像文件对象一样操作它
当close方法被调用的时候,这个buffer会被释放
getvalue() 获取全部内容,跟文件指针没有关系

示例

from io import StingIO
sio = StringIO() # 跟文件操作类似
sio.write("test context")
sio.seek(0)
print(sio.getvalue())
print(sio.readline())
sio.close()
  • BytesIO

io模块中类: from io import BytesIO
内存中,开辟的一个二进制模式的buffer,可以像文件对象一样操作它
当close方法被调用的时候,这个buffer会被释放
getvalue() 获取全部内容,跟文件指针没有关系

与StringIO相似。
一般来说,磁盘操作比内存操作慢的多,内存足够的情况下,一般的优化是少落地,减少磁盘IO的过程,可大大提高程序的运行效率。

4. 路径操作

3.4版本之前:os.path模块

示例1

from os import path
p = path.join('/etc'. 'sysconfig', 'network')
print(type(p), p)
print(path.exists(p))
print(path.split(p))
print(path.abspath('.'))
p = path.join('o:/', p, 'text.txt')
print(path.dirname(p))
print(path.basename(p))
print(path.splitdrive(p)) # window下使用
3.4版本之后:pathlib模块

示例1

from pathlib import Path
p = Path()
p.absolute() #绝对路径
p = p.joinpath('a','b')
p.absolute()
p = p / 'c'  #拼接 等价于 p / = 'c' , p = p.joinpath('c')
#目录初始化
p = Path() #当前目录
p = Path('a', 'b', 'c/d') #当前目录下a/b/c/d
p = Path('/etc')

leafgood
183 声望15 粉丝

踏入IT这个圈子,就成了一名玩家,想要走的更远,就要不断给自己技能加点才行。