一、文件IO常用操作
1、open打开、read读取、write写入、close关闭、readline行读取、readlines多行读取、seek文件指针操作、tell指针位置
2、open(file,mode="r",buffering=-1,encoding=None,errors=None,newline=None,closefd=True,opener=None)
3、encoding='cp936'/‘utf-8’,一个是windows下的,一个linux下的
4、open的参数:
1、file----打开或要创建的文件,如果不指定路径,默认是当前路径
2、mode(模式)
1、r,缺省的,表示只读打开,不写则r
2、w,只写打开----如果文件在,则覆盖之前内容,如果文件不存在,则创建文件
3、x,创建并写入一个新文件只写打开,原来有则创建失败
4、a,写入打开,原来有则追加
5、b,二进制模式,rb,wb
6、t,缺省的,文本模式
7、+读写打开一个文件,将缺少的权限补上,r+,w+,x+,a+
3、mode=r指针起始在0
mode=a指针起始在EOF,end of file
tell()显示指针现在的位置
seek(offset[,whence])移动指针位置,offset偏移多少字节,whence表示从哪里开始
4、文本模式下:
1、whence=0,缺省值,表示从头开始,offset只能接受正整数
2、whence=1,表示从当前位置,offset只接受0
3、whence=2,表示从EOF位置,offset只接受0
5、二进制模式下:
1、whence=0,缺省值,表示从头开始,offset只能是正整数
2、whence=1,表示从当前位置,offset可正可负
3、whence=2,表示从EOF位置,offset可正可负
4、向前的负数,不可超界
5、buffering:缓冲区
1、-1表示使用缺省大小,如果是二进制模式,使用io.DEFAULT_BUFFER_SIZE值,一般4096或8192
2、文本模式,如果是终端,是行缓存,不是的话,按照二进制的缓存模式
3、参数含义
1、0只在二进制模式下使用,表示关闭buffer
2、1只在文本模式使用,表示使用行缓冲,见到换行符就flush
3、大于1用于指定buffersize,但是文本模式没什么用
4、flush()将缓冲区数据写入磁盘,close()关闭前会flush一下
5、写法
import io
f = open('text','w+b',16)
print(io.DEFAULT_BUFFER_SIZE)
f.write('magedu.com'.encode())
f.seek(0)
f.write('www.magedu.com'.encode())
f.flush()
f.close()
6、文本模式行缓冲
f = open('text','w+',1)
f.write('mag')
f.write('mag'*4)
f.write('\n')
f.write('edu')
f.seek(0)
f.read()
f.close()
7、无缓存的二进制文件,FIFO文件
f = open('text','w+b',0)
f.write(b'm')
f.write(b'a')
f.write(b'g')
f.write('magedu'.encode()*4)
f.write(b'\n')
f.write(b'Hello\nPython')
6、文本模式,一般都用默认缓存大小
二进制模式,是一个个字节的操作,可以指定buffer大小
一般来说,默认缓冲大小是最好的选择
一般编程中,需要写磁盘,调用flush(),不需要则在自动flush时或close()时
7、其他参数
1、errors:什么样的编码错误将被捕获:None和strict表示有编码错误将抛出ValueError错误,ignore表示忽略
2、newline:文本模式中,换行的转换,可以为None,"、","\r","\n","\r\n"读时,None表示上面符号都变成"\n",表示不会自动转换通用换行符,其他合法字符表示换行符就是指定字符,按照指定字符分行写时,None表示"\n"都会被替换为系统缺省行分隔符"os.linesep","\n"或""表示"\n"不替换,其他合法字符表示"\n"会被替换成指定字符
3、closefd:关闭文件秒数符,True表示关闭,False表示在close后还保持这个秒数符
8、read(size=-1)
read表示读取多少字符或字节,负数或None表示全部读取
9、readline(size=-1)
一行行读取文件内容,size设置一次能读取行内几个字符或字节。
10、readlines(hint=-1)
读取所有行的列表,指定hit返回指定的行数
11、其他:
1、seekable()是否可seek
2、readable()是否可读
3、writable()是否可写
4、closed是否已关闭
12、上下文管理
1、使用finally来关闭文件
f = open('test','r+')
try:
f.write('abc')
finally:
f.close()
print(f.closed)
2、使用with as关键字
with open('test') as f:
f.write('abc')
print(f.closed)
3、f = open('test','r+')
with f:
f.write('abc)
print(f.closed)
二、StringIO
1、io模块中的类,在内存中开辟一个文本模式的buffer,可以像文件对象一样操作,close则关闭,内存足够少落地,提高效率
from io import StringIO
sio = StringIO()
print(sio.readable(),sio.seekable(),sio.writable())
sio.write('magedu\nPython')
sio.seek(0)
print(sio.readline())
sio.seek(0)
print(sio.readlines())
print(sio.getvalue())
sio.close()
print(sio.closed)
2、getvalue()
获得全部内容,跟指针没有关系
三、BytesIO
1、io模块中的类,开辟二进制的buffer,操作与StringIO类
from io import BytesIO
bio = BytesIO()
print(bio.readable(),bio.writable(),bio.seekable())
bio.write(b'magedu\nPython')
bio.seek(0)
print(bio.readline())
print(bio.getvalue())
bio.close()
print(bio.closed)
四、file-like对象
1、类文件对象,可以像文件对象一样操作
2、socket对象、输入输出对象(stdin、stdout)都是类文件对象
from sys import stdout
from sys import stdin
f = stdout
print(type(f))
print(f.write('abc'))
stdin不能写,stdout不能读
五、路径操作
1、路径操作模块
3.4版本之前
1、os.path模块
from os import path
p = path.join('/etc','sysconfig','network')
print(type(p),p)
print(path.exists(p))
print(path.split(p)) #取*head,tail
print(path.abspath('.')) #绝对路径,当前工作路径,"."是当前路径
p = path.join('o:/',p,'test.txt')
print(path.dirname(p)) #当前路径
print(path.basename(p)) #basename
print(path.splitdrive(p)) #驱动器
3.4版本之后
2、pathlib模块
from pathlib import Path
p = Path()
print(type(p)) # windows和Linux不同
print(p) # '.',两个系统一样
print(p.absolute()) # 不同
p = p.joinpath('a','b') # 路径操作
print(p)
print(p.absolute())
p = p/'c'/'d' # 可以直接操作路径
p/='e''/''f' # /=类似于+=
print(p)
p1 = Path('/etc') # 从根开始,绝对路径
print(p1)
print(p1.absolute())
# p2 = '/etc'/'sysconfig' 字符串拼接,p2不在,不能直接操作
p2 = Path('.')
p2 = p2 / '/etc/' / 'sysconfig' # /etc,强行从根开始
p3 = Path('a','b','c')
print(p2)
print(p2.parts) # 拿属性,生成元组,方便迭代
p4 = p2.joinpath('a','b','c')
print(p4)
print(str(p4),'\n',bytes(p4)) # 路径字符串
print(p4.parent)
print(p4.parent.parent)
print(p4.parents) # 可迭代对象
print(list(p4.parents)) # 最亲的开始
print(list(p4.parents)[0]) # 取第一个
print(next(iter(p4.parents))) # list不可迭代,换成iter,a = iter(p4.parents)---->next(a)
p5 = Path()
print(list(p5.absolute().parents)) # p5是空的,用绝对路径包一下
3、属性操作
from pathlib import Path
p = Path('a','b','c','d')
p /= 'e''/''f'
p = p.joinpath('xx.ifg')
p1 = Path(str(p) + '.gz')
print(p1)
print(p.name) # 目录的最后一部分,全部
print(p.stem) # 目录的最后一个部分,没有后缀名
print(p.suffix) # 目录的最后一部分的扩展名
print(p1.suffixes) # 返回多个扩展名列表
print(p1.with_suffix('.rgz')) # 替换扩展名
print(p1.with_name('test.tgz')) # 替换name
print(p1.parent/'test.tgz') # 同上
4、命令
from pathlib import Path
p = Path()
p = p/'/a'/'b'/'c'
print(p.cwd()) # 当前工作路径,与描述的路径无关
print(p.home()) # 当前home,与其他无关
print(p.is_dir()) # 当前描述的路径是不是目录,不过目前没有,所以False
print(p.is_file()) # 同上,不存在则False
print(p.is_symlink()) # 软连接
print(p.is_socket()) # socket文件
print(p.is_block_device()) # 块设备
print(p.is_char_device()) # 字符设备
print(p.is_absolute()) # 绝对路径
# print(p.resolve())
# 返回一个新路径,是当前Path对象的绝对路径,如果是软连接,则被解析,但不存在的话,则报错
# 临时可以用absolute,推荐使用resolve
print(p.exists())
# p.rmdir() # 删除空目录
p1 = Path('')
p1 /= p1/'D:/'/'QQLive'/'mysql.tar.gz'
p1 = p1.with_name('test.txt')
p1.touch() #创建
print(p1.resolve())
5、
print(p1.as_uri()) # 生成url
p2.mkdir() #创建目录,p2.mkdir(parents=True)
Path().iterdir() # 迭代当前目录,是个生成器
for x in Path().iterdir():
if x.is_dir():
print(x)
6、通配符,rglob(*.py)这个是递归获取,和最后一种一样
print(list(Path('D:/','QQLive').glob('*.gz')))
print(list(Path('D:/','QQLive').glob('*/*.gz'))) # 找本层和上一层
print(list(Path('D:/','QQLive').glob('**/*.gz'))) # 找本层和任意层
7、匹配 match
from pathlib import Path
print(Path('a/b.py').match('.py'))
print(Path('.py').match('*.py')) # .py是隐藏文件,用*是匹配0个
print(Path('a/b/c.py').match('a/*py'))
print(Path('a/b/c.py').match('a/*/*py')) # */,没有或一级
print(Path('a/b/c.py').match('a/**/*py'))
8、文件操作
from pathlib import Path
p = Path('D:/QQlive/hello')
p.mkdir()
p = p/'hello.txt'
p.touch()
print(p.match('*txt'))
# p.open('r+') # 没有则w+
with p.open('r+') as f:
f.write('abc')
# 直接调用下面的也一样
p.write_text('abc')
p.read_text(2)
p.write_bytes(b'hello')
p.read_bytes()
2、os模块
import os
import sys
print(os.name)
# print(os.uname()) # linux的命令
print(os.listdir('D:/')) # 返回目录内容列表
print(sys.platform) # 显示win32,64
print(os.listdir())
print(os.stat('D:/')) # 获取权限等属性
os.chmod('test',0o777)
os.chown(path,uid,gid) # 改变属主,属组
3、shutil模块
import os
import shutil
with open('o:/test','r+') as f1:
f1.write('abcde')
f1.flush()
f1.seek(0)
with open('0:/test1','w+') as f2:
shutil.copyfileobj(f1,f2)
# 复制内容
shutil.copyfile('D:\QQLive/test.txt','D:\QQLive/test2.txt')
# 复制内容,本质上还是obj的用法
shutil.copymode('D:\QQLive/test.txt','D:\QQLive/test2.txt')
# 仅仅复制权限
shutil.copystat('test','test1')
# 复制元数据,包括权限
shutil.copytree('src','dst')
# copy2可以拷贝权限属性内容,比copy多属性
# src必须存在,dst必须不存在,递归复制目录,默认使用copy2,不拷贝隐藏文件
shutil.rmtree('path')
# 递归删除,慎用,不是原子操作,删到一半失败了,前面的没了
os.rename('D:/QQlive/test2.txt','D:/dst')
# 这就是move,从哪里改到哪里
二、csv文件
1、逗号分割的值,也可以自定义分割符
2、被行分隔符,列分隔符划分成行和列的文本文件
3、行分割符为、\r\n,最后一行可以没有换行符
4、列分隔符常为逗号或者制表符
5、每一行成为一条记录record
6、字段可以双引号括起来,也可以不使用,如果字段中出现了双引号,逗号,换行符必须使用双引号括起来,如果字段的值是双引号,使用两个双引号表示一个转义
7、
import os
s = """\ # 第一行换行去掉,小技巧
1,tom,20,
2,jerry,16,
3"""
with open('D:/QQlive/test.csv','w') as f:
for line in s.splitlines():
f.write(line +"\n")
8、
import csv
from pathlib import Path
p = Path('D:/QQlive/test.csv')
if not p.parent.exists():
p.parent.mkdir(parents=True)
s = '''\
1,tom,20,
2,jerry,16,
3,,,
'''
line1 = [1,"tom",20,'']
line2 = [2,"tom",20,'']
line3 = [line1, line2]
with open(str(p),'w') as f:
writer = csv.writer(f)
writer.writerow(line1)
writer.writerow(line2)
writer.writerows(line3)
with open(str(p)) as f:
reader = csv.reader(f)
for line in reader:
if line:
print(line)
9、ini文件,配置文件
from configparser import ConfigParser
cfg = ConfigParser()
cfg.read('D:/QQlive/test.ini')
cfg.sections() # 区
for section in cfg.sections():
for option in cfg.options(section): # key
print(section,option)
# for k,v in cfg.items():
# print(k,v)
for k,v in cfg.items(section):
print(k,v)
if not cfg.has_section('test'):
cfg.add_section('test')
cfg.set('test','test1','123')
cfg.set('test','test2','abc')
# 内存中操作,没写入文件内,下面写进去
with open("D:/QQlive/test.ini",'w') as f:
cfg.write(f)
a = cfg.get('test','test1')
print(a)
b = cfg.getint('test','test1')
print(b)
cfg.remove_option('test','test2')
三、序列化和反序列化
1、serialization 序列化
将内存中对象存储下来,变成一个个字节--》二进制
2、deserialization 反序列化
将文件中的一个个字节恢复成内存中对象 《--二进制
3、序列化保存到文件就是持久化
可以将数据序列化后持久化,或者网络传输,也可以将文件中或者网络接受到的字节序列反序列化
4、pickle库,只解决python的序列化
dumps 对象序列化
dump 对象序列化到文件对象,就是存入文件
loads 对象反序列化
load 对象反序列化,从文件读取数据
# 反序列化必须有对应的数据类型,否则报错,尤其是自定义类,必须远程得有
import pickle
lst = 'a b c'.split()
d = dict(zip('abc',range(3)))
with open("D:/QQlive/pickle",'wb') as f:
pickle.dump(lst,f) # 序列化,生成在上面文件中
pickle.dump(d,f)
with open("D:/QQlive/pickle",'rb') as f:
tmp = pickle.load(f) # 反序列化,需要接住
print(tmp)
tmp = pickle.load(f)
print(tmp)
四、json
1、值:双引号引起来的字符串"",数值123,true和false,null,对象{},数组[]
2、字符串,由双引号包起来的任意字符,包括中文
3、数值,正负,整数,浮点数
4、对象:无序的键值对的组合,格式:{key1:value1,..,keyn:valuen},key必须是字符串
5、数组,有序的值的组合:[value1,..,valuen]
6、json类型
Python类型 Json类型
True true
False false
None null 一个空值
str string
int integer
float float
list array
dict object
7、
import json
d={'a':123,'b':['abc',{'c':234}],'d':True,'e':False,'f':None}
print(d)
class AA:
def ser(self):
return 'AA'
a = json.dumps(d)
print(a)
print(json.dumps(AA().ser()))
五、MessagePack二进制的序列化
import json
import msgpack
js = {'a':123,'b':['abc',{'c':234}],'d':True,'e':False,'f':None}
a = json.dumps(js)
print(a)
b = json.loads(a)
print(b)
c = msgpack.packb(js)
print(c)
d = msgpack.unpackb(c,encoding='utf-8') # encoding转换注意
print(d)
转载于:https://blog.51cto.com/13287682/1977594