【第十二天】Python的文件操作

第五章

5.1存储

1.文件

我们知道,py中的数据都保存在内存中,当电脑断电时,就好像患了失忆症
内存中的数据就会消失,另一方面,如果py程序运行结束
那么分配给这个程序的内存空间也会清空,为了长期持续地存储
py必须把数据存储在磁盘中,这样,即使断电或程序结束
数据依然存在

磁盘以文件为单位来存储数据,对于计算机来说,数据的本质就是
有序的二进制数序列,如果以字节为单位,也就是每8位二进制数序列为单位
那么这个数据序列就称为文本,这是因为,8位的二进制数序列正好
对应ASCII编码中的一个字符,而py能够借助文本对象来读写文件

在py中,我们可以通过内置函数open来创建文件对象
在调用open时,需要说明文件名,以及打开文件的方式:

f = open(文件名,方式)

文件名是文件存在于磁盘的名字,打开文件的常用方式有:

"r" #读取已经存在的文件
"w" #新建文件,并写入
"a" #如果文件存在,那么写入到文件的结尾,如果文件不存在,则新建文件并写入

例如:

f = open("test.txt","r")

就是用只读的方式,打开了一个名为test.txt的文件

通过返回上面的对象,我们可以读取文件:

content = f.read(10)        #读取10个字节的数据
content = f.readline()      #读取一行
content = f.readlines()     #读取所有行,储存在列表中,每个元素是一行

如果以"w"或"a"方式打开,那么我们就可以写入文本:

f = open('test.txt','w')
f.write('i like apple')     #将'i like apple'写入文件

如果想写入一行,则需要在字符串末尾加上换行符
在UNIX系统中,换行符为"\n"
在windows系统中,换行符为"\r\n"

打开文件端口将占用计算机资源,因此,在读写完成后
应该及时的用文件对象的close()方法关闭文件:

f.close()

用法延伸:
r:以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式

rb:以二进制只读方式打开一个文件。文件指针将会放在文件的开头

r+:以读写方式打开一个文件。文件指针将会放在文件的开头

rb+:以二进制读写方式打开一个文件。文件指针将会放在文件的开头

w:以写入方式打开一个文件。如果该文件已存在,则将其覆盖。如果该文件不存在,则创建新文件。

wb:以二进制写入方式打开一个文件。如果该文件已存在,则将其覆盖。如果该文件不存在,则创建新文件。

w+:以读写方式打开一个文件。如果该文件已存在,则将其覆盖。如果该文件不存在,则创建新文件。

wb+:以二进制读写格式打开一个文件。如果该文件已存在,则将其覆盖。如果该文件不存在,则创建新文件。

a:以追加方式打开一个文件。如果该文件已存在,文件指针将会放在文件结尾。
也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,则创建新文件来写入。

ab:以二进制追加方式打开一个文件。如果该文件已存在,则文件指针将会放在文件结尾。
也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,则创建新文件来写入。

a+:以读写方式打开一个文件。如果该文件已存在,文件指针将会放在文件的结尾。
文件打开时会是追加模式。如果该文件不存在,则创建新文件来读写。

ab+:以二进制追加方式打开一个文件。如果该文件已存在,则文件指针将会放在文件结尾。
如果该文件不存在,则创建新文件用于读写。

来源链接:https://juejin.im/post/5ab22accf265da239a5fb172

2.上下文管理器

文件操作常常和上下文管理器一起使用,上下文管理器(context manager)
用于规定某个对象的使用范围,一旦进入或者离开该使用范围,则会有特殊操作被调用
比如为对象分配或者释放内存,上下文管理器可用于文件操作,对于文件操作来说
我们需要在读写结束时关闭文件,程序员经常会忘记关闭文件,无谓占用资源
上下文管理器可以在不需要文件的时候,自动关闭文件

下面时一段常规的文件操作程序:

#常规文件操作

f = open("new.txt","w")
print(f.closed)            #检查文件是否打开
f.write("hello world!")
f.close()
print(f.closed)            #打印True

如果我们加入上下文管理器的语法,就可以把程序改写为:

#使用上下文管理器

with open("new.txt","w") as f:
    f.write("hello world!")
print(f.closed)

第二段程序就使用了with...as...结构,上下文管理器有隶属于它的程序块
当隶属的程序块执行结束时,也就是语句不再缩进时,上下文管理器就会自动关闭文件
在程序中,我们调用了f.closed属性来验证是否已经关闭
通过上下文管理器,我们相当于用缩进来表达文件对象的打开范围
对于复杂的程序来说,缩进的存在能让程序员更清楚的意识到文件在哪些阶段打开
减少忘记关闭文件的可能性

上面的上下文管理器基于f对象的exit()特殊方法
使用上下文管理器的语法时,py会在进入程序块之前调用文件对象的enter()方法
在结束程序块的时候调用文件对象的exit()方法
在文件对象的exit()中,有self.close()语句
因此,在使用上下文管理器时,我们就不必用明文关闭文件了

任何定义了enter()方法和exit()的对象都可以用于上下文管理器
下面,我们自定义一个类Vow,并定义它的enter()方法和exit()方法
因此,由Vow类的对象可以用于上下文管理器:

class Vow(object):
    def __init__(self,text):
        self.text = text
    def __enter__(self):
        self.text = "i say:" + self.text    #增加前缀
        return self                         #返回一个对象
    def __exit__(self,exc_type,exc_value,traceback):
        self.text = self.text + "!"         #增加后缀
with Vow("I'm fine") as myVow:
    print(myVow.text)
    
print(myVow.text)
i say:I'm fine
i say:I'm fine!

初始化对象时,对象的text属性是"I'm fine"我们可以看到
在进入上下文和离开上下文时,对象调用了enter()方法和exit()方法
从而造成对象的text属性改变

enter()返回一个对象,上下文管理器会使用这一对象作为as所指变量
我们自定义的enter()返回的是self,也就是新建的Vow类对象本身
enter()中,我们为text属性增加了前缀"i say:"
exit()中,我们为text属性增加后缀"!"

值得注意的是,exit()有四个参数,当程序块中出现异常时
exit()参数中exc_type,exc_value,traceback用于描述异常
我们可以根据这三个参数进行相应的处理,如果正常运行结束,则这三个参数都是None

3.pickle包

我们能把文本存于文件,但py中最常见的是对象,当程序结束或者计算机关闭时
这些存在于内存的对象会消失,那么,我们能否把对象保存在磁盘上呢

利用pickle包就可以做到这一点,英文里,pickle是腌菜的意思
大航海时代的海员们常把蔬菜做成腌菜,装在罐头里带着走
py中的pickle也有类似的意思,通过pickle包,我们可以把某个对象保存下来
再存成磁盘里的文件

实际上,对象的存储分为两步,第一步,我们将对象在内存里的数据直接抓取出来
转换成一个有序的文本,即所谓的序列化(Serialization),第二步
将文本存入文件,等到需要时,我们从文件中读出文本,再放入内存
就可以获得原有的对象,下面是一个具体的例子
首先是第一步序列化,将内存中的对象转换为文本流:

import pickle
class Bird(object):
    have_feather = True
    reproduction_method = 'egg'
summer = Bird()                          #创建对象
pickle_string = pickle.dumps(summer)     #序列化对象

使用pickle包的dumps()方法可以将对象转换成字符串的形式
随后,我们用字节文本的存储方法,将该字符串储存在文件
继续第二步

with open("summer.pkl","wb") as f:
    f.write(pickle_string)

上面程序故意分成了两步,以便更好的展示整个过程
其实,我们可以使用dump()的方法,一次完成两步:

import pickle

class Bird(object):
    have_feather = True
    reproduction_method = 'egg'
summer = Bird()                 
with open("summer.pkl","wb") as f:
    pickle.dump(summer,f)         #有序化并保存对象

对象summer将存储在文件summer.pkl中
有了这个文件,我们就可以在必要的时候读取对象了
读取对象与存储对象的过程正好相反,首先,我们从文件中读取文本
然后使用pickle的loads()方法,将字符串形式的文本转换为对象
我们也可以使用pickle的load()方法,将上面两步合并

有的时候,仅仅是反向恢复还不够,对象依赖于它的类
所以py在创建对象时,需要找到相应的类
因此当我们从文本中读取对象时,程序中必须已经定义过类
对于py总是存在的内置类,如列表,词典,字符串等
不需要再在程序中定义,但是对于用户自定义的类,就必须要先定义类
然后才能在文件中载入该类的对象
下面是一个读取对象的例子:

import pickle

class Bird(object):
    have_feather = True
    reproduction_method = 'egg'
summer = Bird()                 
with open("summer.pkl","rb") as f:
    summer = pickle.load(f)
print(summer.have_feather)       #打印True     

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,978评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,954评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,623评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,324评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,390评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,741评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,892评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,655评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,104评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,569评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,254评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,834评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,725评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,950评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,260评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,446评论 2 348