Python学习笔记(七)
Python学习笔记(七)
IO编程
IO在计算机中指Input/Output,也就是输入和输出。Input Stream就是数据从外面(磁盘、网络)流进内存,Output Stream就是数据从内存流到外面去。
文件读写
读文件
使用Python内置的open()
函数打开一个文件,该函数返回一个文件对象。
'''
file : 文件路径
mode : 文件打开方式
buffer : 缓存
encoding : 按指定编码读取
errors : 表示如果遇到编码错误后如何处理
'''
open(file="",mode=""[encoding="",errors="",buffering=""])
Python打开文件的方式:
'r':只读,文件一定要存在,否则报错
'w':只写,文件不存在则自动创建,文件存在清空之前内容
'a':追加,文件不存在则自动创建,文件存在接着后面追加
'r+'/'w+':读写方式打开
'a+':追加和读写方式打开
'rb','wb','ab','rb+','wb+','ab+':二进制方式打开
读取文件的方法:
-
read([size])
:一次读取文件的全部内容 -
readline([size])
:每次读取一行内容 -
readlines([size])
:一次读取所有内容并按行返回list
用read()
读取文件:
f = open('C:/blog/1.txt','r')
print(f.read())
f.close()
运行结果:
Good morning
Yesterday
用readline()
读取文件:
f = open('C:/blog/1.txt','r')
print(f.readline().strip())
print(f.readline().strip())
f.close()
strip()
函数的作用是把末尾的\n
去掉。
用readlines()
读取文件:
f = open('C:/blog/1.txt','r')
for line in f.readlines():
print(line.strip())
f.close()
如果文件很小,read()
一次性读取最方便;如果不能确定文件大小,反复调用read(size)
比较保险;如果是配置文件,调用readlines()
最方便。
由于文件读写时都有可能产生IOError
,一旦出错,后面的f.close()
就不会调用。所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用try ... finally
来实现:
try:
f = open('C:/blog/1.txt','r')
print(f.read())
finally:
f.close()
Python引入了with
语句来自动帮我们调用close()
方法:
with open('C:/blog/1.txt', 'r') as f:
print(f.read())
这和前面的try ... finally
是一样的,但是代码更佳简洁,并且不必调用f.close()
方法。
写文件
-
write(str)
:将字符串写入到文件 -
writelines(sequence_of_strings)
:写多行到文件,参数为可迭代对象
写入字符串到文件:
f = open('C:/blog/1.txt','w')
for n in range(100):
f.write("test write"+'\n')
f.close()
注意:当写入的字符大小少于缓存大小时,需要在调用close()
或者flush()
方法之后才能在文件里面查看。
StringIO和BytesIO
StringIO
在内存中读写字符串。把str
写入到StringIO
:
from io import StringIO
f = StringIO()
f.write("hello")
f.write(" ")
f.write("world")
print(f.getvalue())
运行结果:
hello world
getvalue()
用于获得写入后的字符串。
读取StringIO
:
from io import StringIO
f = StringIO("hello!\nhi!\ngoodbye")
while(True):
s = f.readline()
if s == "":
break
print(s.strip())
运行结果:
hello!
hi!
goodbye
BytesIO
BytesIO实现了在内存中读写bytes。
在内存中写入bytes:
from io import BytesIO
f = BytesIO()
f.write("汉字".encode("utf-8"))
print(f.getvalue())
运行结果:
b'\xe6\xb1\x89\xe5\xad\x97'
在内存中读取bytes:
from io import BytesIO
f = BytesIO(b'\xe6\xb1\x89\xe5\xad\x97')
print(f.read())
运行结果:
b'\xe6\xb1\x89\xe5\xad\x97'
序列化
变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling。反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。
Python提供了pickle
模块来实现序列化:
import pickle
d =dict(name = 'bob',age = 20 ,score = 60)
f = open('C:/blog/1.txt','wb')
f.write(pickle.dumps(d))
f.close()
pickle.dumps()
方法把任意对象序列化成一个bytes
,然后,就可以把这个bytes
写入文件。或者用另一个方法pickle.dump()
直接把对象序列化后写入一个file-like Object。
把对象从磁盘读取到内存:
import pickle
f = open('C:/blog/1.txt','rb')
d = pickle.load(f)
print(d)
f.close()
运行结果:
{'name': 'bob', 'score': 60, 'age': 20}
pickle.load()
方法从一个file-like Object
中直接反序列化出对象。
JSON
JSON表示的对象是标准的JavaScript语言的对象,方便我们在不同的编程语言之间传递对象。Python内置的json
模块提供了非常完善的Python对象到JSON格式的转换:
import json
d = dict(name='Bob', age=20, score=88)
print(json.dumps(d))
运行结果:
'{"age": 20, "score": 88, "name": "Bob"}'
dumps()
方法返回一个str
,内容就是标准的JSON。类似的,dump()
方法可以直接把JSON写入一个file-like Object。
用loads()
或者对应的load()
方法,前者把JSON的字符串反序列化:
json_str = '{"age": 20, "score": 88, "name": "Bob"}'
print(json.loads(json_str))
运行结果:
{'score': 88, 'name': 'Bob', 'age': 20}
将class
的实例对象都无法序列化为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
}
s = Student('Bob', 20, 88)
print(json.dumps(s, default=student2dict))
运行结果:
{"score": 88, "age": 20, "name": "Bob"}
把任意class的实例变为dict:
json.dumps(s, default=lambda obj: obj.__dict__)
同样,将JSON字符串转换成对象也需要写一个转换函数:
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))
运行结果:
<__main__.Student object at 0x0059CCF0>
参考资料:廖雪峰的官方网址
上一篇: 剑指offer之反转链表(java)
下一篇: python爬虫--05 正则表达式