文件读写
在Python中,文件读写是通过open()函数打开的文件对象完成的。使用with语句操作文件IO是个好习惯。
try:
f = open('1.txt', 'r') #rb写二进制
#f = open('1.txt', 'w') #wb读二进制
f.read().decode('utf8')
#f.write('test').encode('utf8')
finally:
if f:
f.close()
用with写:
with open('1.txt', 'r') as f:
print f.read()
如果文件很小,read()一次性读取最方便;如果不能确定文件大小,反复调用read(size)比较保险;如果是配置文件,调用readlines()最方便
模式 |
描述 |
r |
以读方式打开文件,可读取文件信息。 |
w |
以写方式打开文件,可向文件写入信息。如文件存在,则清空该文件,再写入新内容 |
a |
以追加模式打开文件(即一打开文件,文件指针自动移到文件末尾),如果文件不存在则创建 |
r+ |
以读写方式打开文件,可对文件进行读和写操作。 |
w+ |
消除文件内容,然后以读写方式打开文件。 |
a+ |
以读写方式打开文件,并把文件指针移到文件尾。 |
b |
以二进制模式打开文件,而不是以文本模式。该模式只对Windows或Dos有效,类Unix的文件是用二进制模式进行操作的。 |
read(size) # 读取所有内容至字符串,若设定了size,就最多读取size个字节的内容
readline(size) # 每次读取一行内容
readlines() # 读取所有内容并按行返回list
write() # 将字符串写入到文件
writelines() # 接受一个字符串列表作为参数,将它们写入文件
ps:当使用输入方法如 read() 、readline() 、readlines() 从文件中读取行时, Python 并不会删除行结束符. 这个操作被留给了程序员.
类似地, 输出方法 write() 或 writelines() 也不会自动加入行结束符. 你应该在向文件写入数据前自己完成
文件迭代
for eachline in f: # 一行行访问文件
操作系统差异
Linux、Mac:换行符(
) 路径分隔符(/)
windows、dos:换行符(
) 路径分隔符()
os模块中考虑了上面这些:
linesep 系统行分隔符
sep 系统路径分隔符
pathsep 不同路径分隔条
curdir 当前工作目录
pardir 当前工作目录的父目录
>>> print 'aa' + os.linesep + 'bb' aa bb >>> print 'aa' + os.sep + 'bb' aab >>> print 'aa' + os.pathsep + 'bb' aa;bb >>> print os.curdir . >>> print os.pardir ..
目录操作
把两个路径合成一个时,不要直接拼字符串,而要通过os.path.join()函数,这样可以正确处理不同操作系统的路径分隔符
同样的道理,要拆分路径时,也不要直接去拆字符串,而要通过os.path.split()函数,这样可以把一个路径拆分为两部分,后一部分总是最后级别的目录或文件名
得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd()
返回指定目录下的所有文件和目录名:os.listdir()
检验给出的路径是否是一个文件:os.path.isfile()
检验给出的路径是否是一个目录:os.path.isdir()
判断是否是绝对路径:os.path.isabs()
检验给出的路径是否真地存:os.path.exists()
返回一个路径的目录名和文件名:os.path.split()
分离扩展名:os.path.splitext()
获取路径名:os.path.dirname()
获取文件名:os.path.basename()
获取文件属性:os.stat(file)
给出当前平台使用的行终止符:os.linesep Windows使用'
',Linux使用'
'而Mac使用'
'
创建目录
os.mkdir("file")
复制文件
shutil.copyfile("oldfile","newfile") #oldfile和newfile都只能是文件
shutil.copy("oldfile","newfile") #oldfile只能是文件夹,newfile可以是文件,也可以是目标目录
复制文件夹
shutil.copytree("olddir","newdir") #olddir和newdir都只能是目录,且newdir必须不存在
移动文件/目录
shutil.move("oldpos","newpos")
重命名文件/目录
os.rename("oldname","newname")
删除文件
os.remove("file")
删除目录
os.rmdir("dir") #只能删除空目录
shutil.rmtree("dir") #空目录、有内容的目录都可以删
转换目录
os.chdir("C:\123") #将当前目录设为 "C:123", 相当于DOC命令的 CD C:123
file-like Object
像open()函数返回的这种有个read()方法的对象,在Python中统称为file-like Object。除了file外,还可以是内存的字节流,网络流,自定义流等等。file-like Object不要求从特定类继承,只要写个read()方法就行。
StringIO就是在内存中创建的file-like Object,常用作临时缓冲。
序列化
把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。
反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。
如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,例如JSON
JSON和Python内置的数据类型对应如下:
JSON类型 | Python类型 |
{} | dict |
[] | list |
"string" | 'str'或u'unicode' |
1234.56 | int或float |
true/false | True/False |
null | None |
对于简单数据类型(string、unicode、int、float、list、tuple、dict),可以直接处理。
序列化
dumps()方法返回一个str,内容就是标准的JSON。
dump()方法可以直接把JSON写入一个file-like Object。
反序列化
loads()把JSON的字符串反序列化
load()从file-like Object中读取字符串并反序列化
>>> import json
>>> d = dict(name='David', age=20, score=100)
>>> d_encode = json.dumps(d)
>>> d_encode
'{"age": 20, "score": 100, "name": "David"}'
>>> with open('D:\1.txt', 'wb') as f:
d_encode_file = json.dump(d, f)
>>> d_decode = json.loads(d_encode)
>>> d_decode
{u'age': 20, u'score': 100, u'name': u'David'}
>>> with open('D:\1.txt', 'rb') as f:
d_decode_file = json.load(f)
>>> d_decode_file
{u'age': 20, u'score': 100, u'name': u'David'}
将class的实例对象encode,decode为json
import json
class Student(object):
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
def student2dict(std):
return {
'name': std.name,
'age': std.age,
'score': std.score
}
def dict2student(d):
return Student(d['name'], d['age'], d['score'])
s = Student('David', 20, 100)
print(json.dumps(s, default=student2dict))
#可选参数default就是把任意一个对象变成一个可序列为JSON的对象
json_str = '{"age": 20, "score": 88, "name": "Bob"}'
print(json.loads(json_str, object_hook=dict2student))
#loads()方法首先转换出一个dict对象,传入的object_hook函数负责把dict转换为Student实例
2015-05-10