输入输出: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)

results matching ""

    No results matching ""