云学python (第5章对象带你飞之储存 上下文管理器pickle 包)《vamei-从Python开始学编程》 笔记

本文介绍了Python中的上下文管理器及其工作原理,通过with语句简化文件操作,确保资源得到正确释放。同时讲解了pickle包的使用,包括如何序列化和反序列化对象,以及在恢复对象时对类定义的需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2.上下文管理器

文件操作常常和上下文管理器一起使用。上下文管理器(context manager)用于规定某个对象的使用范围。一旦进入或者离开该使用范围, 则会有特殊操作被调用,比如为对象分配或者释放内存。 

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

#常规文件操作

f = open('/Users/huaweimatebook16/python入门/text2.txt','w')
f.write('I like apple iii\n''sss\n')
f.close()
f = open('/Users/huaweimatebook16/python入门/text2.txt','r')
content = f.readlines()
print(content)
f.close()
print(f.closed)

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

#使用上下文管理器

with open('/Users/huaweimatebook16/python入门/text2.txt','w')as f:
    f.write("Hello World!")

print(f.closed)

第二段程序就使用了 with...as...结构。上下文管理器有隶属于它的程序块,当隶属的程序块执行结束时,也就是语句不再缩进时,上下文管理器就会自动关闭文件。对于复杂的程序来说,缩进的存在能让程序员更清楚地意识到文件在哪些阶段打开,减少忘记关闭文件的可能性。

上面的上下文管理器基于f对象的__exit__()特殊方法。使用上下文管理器的语法时,Python会在进入程序块之前调用文件对象的__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,traceack):
        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_value,exc_value,traceack用于描述异常,可以根据这三个参数进行相应的处理。如果正常运行结束,则这三个参 数都是None。

3. pickle 

利用Pythonpickle包就可以做到把对象保存到磁盘上。英文里,pickle是腌菜的意思。大航海时代的海员们常把蔬菜做成腌菜,装在罐头里带着走。Python中的pickle也有类似的意思

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

下面是一个具体的例子,首先是第一步序列化,将内存中的对象转换为文本流:

import pickle

class Bird(object):
    have_feather = True
    reproduction_method = "egg"
summer = Bird()
pickle_string= pickle.dumps(summer)

with open('summer.pickle','wb')as f:
    f.write(pickle_string )
print(pickle_string)

使用pickle包的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中。

读取对象与存储对象的过程正好相反。首先,从文件中读出文本。然后使用pickleloads()方法,将字符串形式的文本转换为对象。

有时候,仅仅是反向恢复还不够。对象依赖于它的类,所以Python 在创建对象时,需要找到相应的类所以从文本中读取对象时,程序屮必须已经定义过类。

Python总是存在的内置类,如列表、词 典、字符串等,不需要再在程序中定义。但对于用户自定义的类,就必须要先定义类,然后才能从文件中载入该类的对象。

下面是一个读取对象的例子:

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


​​​​​​​

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值