输入输出:io操作
耐心和恒心总会得到报酬的. --------爱因斯坦
文件读写
打开文件
再进行文件读写之前,有个重要的步骤—将文件打开,同时指定针对文件的读写模式,比如只读,只写,可读可写等等。只有先打开文件才能对文件进行读写操作。
打开文件使用内置函数 open()
:
f = open(‘文件路径’,读写模式)
如:
f = open('/Users/obsession/text', 'w')
其中,读写模式
有以下常用选项:
’r’
: 只读,若文件不存在,则抛出FileNotFoundError
异常’w’
: 只写,将覆盖所有原有内容,若文件不存在则创建文件’a’
: 只写,以追加的方式写入内容,若文件不存在则创建文件’r+’
:可读可写,如文件不存在,则抛出FileNotFoundError
异常’w+’
: 可读可写,若文件不存在则创建文件’a+’
: 可读可写,写入时使用追加模式,若文件不存在则创建文件
以上所有读写模式都是基于文本内容的,如果想要读写二进制内容,可在上面的基础上添加’b’
模式,如rb
,’wb+’
open()
返回的是file
对象,也就是这里的变量f。利用这个对象,我们可以进行文件的读写.
上述打开方式默认UTF-8
编码,如果文件内容并非UTF-8
编码,可以使用encoding
参数指定编码格式,如f = open('/Users/obsession/text', 'w', encoding='gbk’)
写入文件
写入文件使用:
length = f.write('内容')
调用f.write()
将返回写入字符的长度
读取文件
content = f.read()
上述方法将读取文件的所有内容,也可以指定要读取的内容的字符长度
# 读取前30个字节,并移动文件指针
f.read(30)
# 接着再读取30个字节
f.read(30)
# 如果读取到结束位置,f.read()返回空字符串
逐行读取
# 读取一行的内容
f.readline()
# 一次性取出所有行的内容,存入一个list
f.readlines()
关闭文件
每次打开问价后,无论进行了多少读写操作,最终都已定要将文件关闭,因为打开文件会消耗相关系统资源(文件描述符),不使用时应及时释放
关闭文件:
f.close()
还有种方式能自动关闭打开的文件,那就是使用with
语句:
with open(“/Users/apple/scott.txt”,’w’) as f:
f.write(“hello world”)
open()后的file对象会被as关键字赋予变量f,和之前一样,我们用f进行文件读写操作
with语句会在它的代码块执行完毕后,或者代码块抛出异常时,自动关闭文件,为我们省去了f.close()
的步骤
文件系统操作
文件系统操作需要使用内置的os
模块
创建目录
import os os.mkdir(“/Users/apple/scott”)
判断路径是否时一个目录
os.path.isdir(“/Users/apple/scott”)
- 列举目录下的内容
os.listdir(“/Users/apple/scott”)
- 删除目录
os.rmdir(“/Users/apple/scott”)
- 创建文件
创建文件可以使用之前学过的open()
:
f = open(“/Users/apple/scott”)
f.close()
- 判断路径是否是一个文件
os.path.isfile(“/Users/apple/scott”)
- 删除文件
os.remove(“/Users/apple/scott”)
- 重命名文件
os.rename(“/Users/apple/scott/file01”,”file02”)
序列化和反序列化
程序运行时,产生的所有对象都位于内存之中,内存有个特点,那就是非持久的,这就意味着一旦程序结束或者计算机断电,占用的内存将被清空
有时,我们需要把程序运行时内存中的对象,持久化下来,保存在文件系统中,或者传输至网络,比如将下面这样一个类的对象保存在文件中:
class Pair:
def __init__(self, first, second):
self.first = first
self.second = second
pair = Pair(10, 20)
这就涉及到序列化和反序列化了。序列化是将内存中的对象转化为可被存储或可被传输的形式的过程。反序列化是将序列化后的内容恢复回内存中类的对象中的过程:
pickle
python中国内置的pickle
模块用作序列化和反序列化,它的序列化结果是二进制形式
序列化的使用:
import pickle
some_types = pick.dumps(对象)
# -*- coding: utf-8 -*-
# @Author: scottxiong
# @Date: 2019-10-22 13:54:51
# @Last Modified by: scottxiong
# @Last Modified time: 2019-10-22 13:58:21
import pickle
class Person(object):
"""docstring for Person"""
def __init__(self, name, age):
super(Person, self).__init__()
self.name = name
self.age = age
person = Person("Scott",18)
res = pickle.dumps(person)
print(res)
b'\x80\x03c__main__\nPerson\nq\x00)\x81q\x01}q\x02(X\x04\x00\x00\x00nameq\x03X\x05\x00\x00\x00Scottq\x04X\x03\x00\x00\x00ageq\x05K\x12ub.'
上述的person输出乱码,是因为person对象被序列化成二进制所示
对于刚才被序列化的结果,使用pickle.loads()
将其反序列化回对象
p = pickle.loads(res)
print(p.name) #scott
print(p.age) #18
也可以与open()
相结合,将序列化的结果保存在文件中,此时使用pickle.dump()
注意与之前的pickle.dumps()
不同:
with open('/Users/apple/desktop/dump', 'wb') as f:
pickle.dump(person, f)
从文件中反序列化处对象,使用pickle.load()
(注意与之前的pickle.loads()
不同)
with open('/Users/apple/desktop/dump', 'rb') as f:
person = pickle.load(f)
JSON
pickle
使用python专用的序列化格式,序列化后的结果无法做到跨语言使用。另外其序列化结果是二进制,不适合阅读.
JSON相对而言更加通用和流行,并且其结果为文本格式,更具可读性。
同样是刚才的person
对象,可以像这样将它序列化为JSON字符串:
# -*- coding: utf-8 -*-
# @Author: scottxiong
# @Date: 2019-10-22 13:54:51
# @Last Modified by: scottxiong
# @Last Modified time: 2019-10-22 14:41:26
import json
class Person(object):
"""docstring for Person"""
def __init__(self, name, age):
super(Person, self).__init__()
self.name = name
self.age = age
person = Person("Scott",18)
res = json.dumps(person.__dict__)
print(res) #{"age": 18, "name": "Scott"}
import json
json_string = json.dumps(person.__dict__)
print(json_string)
注意上面的结果为字符串类型,另外这里使用了person.__dict__
来获取包含所有person
属性的字典,因为累对象不能直接用于json.dumps()
序列化,而字典可以.
或者使用default
参数,向json.dumps()
告知如何进行从对象到字典的转换,这样便可以不使用__dict__
属性,如下:
def person_to_dict(person):
return {
‘name’: person.name,
‘age’: person.age,
}
json_string = json.dumps(person, default=person_to_dict)
{'name':"scott",'age':18}
json反序列化为对象
def dict_to_person(d):
return Person(d['name'], d['age'])
person = json.loads(json_string, object_hook=dict_to_person)
上述反序列化的过程中,json.loads()
首先会将JSON字符串反序列化为字典,然后使用object_hook
参数进一步从字典转换出Person
对象
与pickle
相似,json
也可以与open()
结合使用,将序列化的结果保存在文件中:
with open('/Users/apple/desktop/json', 'w') as f:
json.dump(person, f, default=person_to_dict)
或从文件中反序列化处对象:
with open('/Users/apple/desktop/json', 'r') as f:
person = json.load(f, object_hook=dict_to_person)