IO编程
f = open('/Users/fish/Desktop/readme.txt', 'r')
content=f.read()
print(content)
f.close()
文件使用完必须关闭,文件对象会占用系统资源,操作系统同时能打开文件数量也是有限的
为了保证每次不论是否文件读碟出现IOError
出错 都能正确关闭文件,通常这么写:
try:
f = open('/path/to/file', 'r')
print(f.read())
finally:
if f:
f.close()
# 使用 python的with语句来自动帮我们调用close()方法
#与try...finall..效果相同代码更简洁
with open('/path/to/file', 'r') as f:
print(f.read())
read()
方法会一次性读取全部内容,如果文件过大会挑战内存
read(size)
每次最多读取size字节的内容
readline()
每次读取一行内容
readlines()
一次性读取所有行,返回一个list
类似文件这种 open()函数返回可以read()的对象,均称为 file-like Object,除此之外还有内存的字节流、网络流、自定义流
二进制文件
默认读取的为UTF-8编码的文本文件,如果为二进制文件,需要用rb
模式打开
>>> f = open('/Users/michael/test.jpg', 'rb')
>>> f.read()
# b'\xff\xd8\xff\xe1\x00\x18Exif\x00\x00...' # 十六进制表示的字节
其它编码格式
对于非UTF-8
编码的文本文件,需要open()
函数需要传入encoding
参数
f = open('/Users/michael/gbk.txt', 'r', encoding='gbk')
当编码不规范,文本中夹杂着非法编码字符时,会发生转码错误(UnicodeDecodeError
),此时可以通过加入参数errors
来指定处理方式,常用的为直接忽略
f = open('/Users/michael/gbk.txt', 'r', encoding='gbk', errors='ignore')
写文件
写文件也是调用open()
函数 只是传入的标识符为w
或者wb
表示写文本文件或写二进制文件
f3 = open('/Users/fish/Desktop/readme.txt', 'wb')
f3.write(b'\xe4\xb8\xad\xe6\x96\x87')
f3.close()
与读文件相同要记得调用
close()
方法,否则可能有部分未写入
与读文件相同,可以通过with
语句 确保自动调用close()方法
with open('/Users/michael/test.txt', 'w') as f:
f.write('Hello, world!')
通过
encoding
参数将字符转为指定编码
w
默认为覆盖模式a
是append模式
StringIO 和 BytesIO
内存中进行读写
from io import StringIO
f4=StringIO("初始\n 字符串")
f4.write("hello,")
f4.write(" ")
f4.write("world!")
print(f4.getvalue()) # getvalue()方法用于获得写入后的内容
#hello, world!
from io import BytesIO
f5=BytesIO()
f5.write("中文".encode("utf-8"))
print(f5.getvalue())
# b'\xe4\xb8\xad\xe6\x96\x87'
要读取StringIO,可以用一个str初始化StringIO,然后,像读文件一样读取:
和StringIO类似,可以用一个bytes初始化BytesIO,然后,像读文件一样读取:
from io import StringIO
f = StringIO('Hello!\nHi!\nGoodbye!')
while True:
s = f.readline()
if s == '':
break
print(s.strip())
# Hello!
# Hi!
# Goodbye!
from io import BytesIO
f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')
f.read()
# b'\xe4\xb8\xad\xe6\x96\x87'
操作文件和目录
操作文件和目录
通过os
模块提供的功能
import os
os.name # posix 操作系统类型(posix表示是Linux、Unix、Mac OS,nt表示是Windows)
os.uname() #查看详细的系统信息
#posix.uname_result(sysname='Darwin', nodename='fishdeMacBook-Pro.local', release='17.5.0', version='Darwin Kernel Version 17.5.0: Fri Apr 13 19:32:32 PDT 2018; root:xnu-4570.51.2~1/RELEASE_X86_64', machine='x86_64')
环境变量
os.environ #操作系统定义的全部环境变量
os.environ.get("PATH") # 获取某个环境变量值
os.environ.get('x', 'default') #
操作文件和目录
操作文件和目录的函数 在os
和os.path
中
import os
currentPath=os.path.abspath(".") # .表示当前路径
print(currentPath) # /Users/fish/Desktop/LYY/Python
joinDir=os.path.join("/Users/fish/Desktop", "testDir") #在目录下新建目录 获取新目录路径
print(joinDir) # /Users/fish/Desktop/testDir
splitDir=os.path.split("/Users/fish/Desktop/testDir")
print(splitDir) #('/Users/fish/Desktop', 'testDir') 获取最后一部分文件或目录
splitext=os.path.splitext("/Users/fish/Desktop/testDir") #获取扩展名 如果最后一部分为目录 则为空
print(splitext) # ('/Users/fish/Desktop/testDir/readme', '.txt')
os.mkdir("/Users/fish/Desktop/testDir2") #新建目录
os.rmdir("/Users/fish/Desktop/testDir2") #删除目录
os.path.join("/Users/fish/Desktop", "readme.txt")
os.rename('/Users/fish/Desktop/readme.txt', '/Users/fish/Desktop/readme.py') # 重命名文件
os.remove('/Users/fish/Desktop/readme.py') # 删除文件
dirlist=os.listdir(".") #获取当前目录下的所有文件夹列表
os.path.isdir(".") # 判断是否为文件夹目录
当合并路径时,不要直接拼接字符串,通过os.path.join()
函数可以正确处理不用操作系统的路径分隔符.
同理,拆分字符串时通过os.path.split()
函数,可以把路径拆分为两部分,后一部分总是最后级别的目录或文件名
os.path.splitext()
可以直接让你得到文件扩展名
在
os
模块中并没有复制文件函数,可以再shutil
模块中提供了copyfile()
函数等使用的文件操作函数
序列化
Python通过pickle
模块实现序列化
import pickle
#序列化
dict1=dict(name="Bob", age=24, score=88)
data=pickle.dumps(dict1)
print(data) #b'\x80\x03}q\...\x04KXu.'
#直接将序列化的内容写入文件
file1=open("/Users/fish/Desktop/readme.txt", "wb")
pickle.dump(dict1, file1)
file1.close()
# 将文件从磁盘读到内存后使用pickle.loads()方法反序列化出对象,
# 也可以直接用pickle.load()方法从一个file-like Object中直接反序列化出对象
file2=open("/Users/fish/Desktop/readme.txt", "rb")
dict2=pickle.load(file2)
file2.close()
print(dict2) #{'name': 'Bob', 'age': 24, 'score': 88}
JSON
dict可以转为json序列化
import json
print(json.dumps(dict1)) # {"name": "Bob", "age": 24, "score": 88}
file1=open("/Users/fish/Desktop/readme.txt", "w")
json.dump(dict1, file1)
file1.close() # 文件内容为 {"name": "Bob", "age": 24, "score": 88}
将class 序列化为 json
import json
#序列化 原理是先将class转为dict 然后将dict序列化json
class Student(object):
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
s = Student('Bob', 20, 88)
#专门写一个转换函数 将 class 转为json
def student2dict(std):
return {
'name': std.name,
'age': std.age,
'score': std.score
}
# 传入更多参数来 指定序列化规则
print(json.dumps(s, default=student2dict)) #{"age": 20, "name": "Bob", "score": 88}
# 可以这么写 对大多数class都有__dict__属性来存储实例变量(__slots__除外)
print(json.dumps(s, default=lambda obj: obj.__dict__))
# 反序列化 原理为将json反序列化为dict 然后转为 class实例
def dict2student(d):
return Student(d['name'], d['age'], d['score'])
json_str = '{"age": 20, "score": 88, "name": "Bob"}'
print(json.loads(json_str, object_hook=dict2student))