(python)序列化自定义对象总结--改了类文件的代码之前的序列化自定义对象怎么办?

python中如果我改了自己之前的类代码,那以前的序列化对象还能反序列化回来吗?

着急的可以跳过代码,直接看底下的结论.

class DemoClass:
    
    #初始版本
    def __init__(self,v1,v2,v3):
        self.v1=v1
        self.v2=v2
        self.v3=v3

    #初始版本
    def f1(self,vf11,vf12):
        print("我是即将要修改的部分")
        return vf11+vf12

    #初始版本,作为被删除的那个函数
    # def f2(self,vf21,vf22):
    #     return vf21-vf22

    #这个函数不能变,用来测试反序列化得到的对象能否正常使用
    def test1(self,testVarieble):
        print("受到的参数是,能看到这一行字说明测试函数一可以使用",testVarieble)

    '''1.1.增加新的方法,没有使用到成员变量
    def newf(self):
        print('我是一个新的方法')'''

    """增加的新方法,要用到成员变量了
    def getv1(self):
        return  v1"""

    '''def bbbb(self):
        print("稀奇古怪")'''

    '''这里看对原来的对象展示一下换名字的变量'''
    # def showv4(self):
    #     print(self.v4)

底下的是测试文件:

import pickle
'''
下面说一下我最关心的问题,自定义对象的序列化和反序列化:
1.如果原来的类定义文件发生了改变,还能不能反序列化,如果不能,怎样才能?
            1.成员方法层面:
                1.增加新的方法,
                2.删除原来的方法,
                3.对原来的方法体做出修改
                4.对原来的方法的参数列表做出修改
            2.成员变量层面(其实这也算是对成员方法的修改):
                1.增加成员变量
                2.删除现有的成员变量
2.和import语句有没有关系?是不是只要导入正确的类就行?
'''
import 储存问题.序列化与反序列化.DemoClass as dm
demo=dm.DemoClass("第一个成员变量v1","第一个成员变量v2","第一个成员变量v3")
result=pickle.dumps(demo)
print(result)
#原始序列化结果(什么改动都没有):        b'\x80\x04\x95\xa6\x00\x00\x00\x00\x00\x00\x00\x8c/\xe5\x82\xa8\xe5\xad\x98\xe9\x97\xae\xe9\xa2\x98.\xe5\xba\x8f\xe5\x88\x97\xe5\x8c\x96\xe4\xb8\x8e\xe5\x8f\x8d\xe5\xba\x8f\xe5\x88\x97\xe5\x8c\x96.DemoClass\x94\x8c\tDemoClass\x94\x93\x94)\x81\x94}\x94(\x8c\x02v1\x94\x8c\x17\xe7\xac\xac\xe4\xb8\x80\xe4\xb8\xaa\xe6\x88\x90\xe5\x91\x98\xe5\x8f\x98\xe9\x87\x8fv1\x94\x8c\x02v2\x94\x8c\x17\xe7\xac\xac\xe4\xb8\x80\xe4\xb8\xaa\xe6\x88\x90\xe5\x91\x98\xe5\x8f\x98\xe9\x87\x8fv2\x94\x8c\x02v3\x94\x8c\x17\xe7\xac\xac\xe4\xb8\x80\xe4\xb8\xaa\xe6\x88\x90\xe5\x91\x98\xe5\x8f\x98\xe9\x87\x8fv3\x94ub.'
'''     
成员方法:
        增加一个成员方法后(该方法未使用成员变量):b'\x80\x04\x95\xa6\x00\x00\x00\x00\x00\x00\x00\x8c/\xe5\x82\xa8\xe5\xad\x98\xe9\x97\xae\xe9\xa2\x98.\xe5\xba\x8f\xe5\x88\x97\xe5\x8c\x96\xe4\xb8\x8e\xe5\x8f\x8d\xe5\xba\x8f\xe5\x88\x97\xe5\x8c\x96.DemoClass\x94\x8c\tDemoClass\x94\x93\x94)\x81\x94}\x94(\x8c\x02v1\x94\x8c\x17\xe7\xac\xac\xe4\xb8\x80\xe4\xb8\xaa\xe6\x88\x90\xe5\x91\x98\xe5\x8f\x98\xe9\x87\x8fv1\x94\x8c\x02v2\x94\x8c\x17\xe7\xac\xac\xe4\xb8\x80\xe4\xb8\xaa\xe6\x88\x90\xe5\x91\x98\xe5\x8f\x98\xe9\x87\x8fv2\x94\x8c\x02v3\x94\x8c\x17\xe7\xac\xac\xe4\xb8\x80\xe4\xb8\xaa\xe6\x88\x90\xe5\x91\x98\xe5\x8f\x98\xe9\x87\x8fv3\x94ub.'
        结果:与原始对象序列化的结果相同,可以使用各项功能,包括新增的函数
        结论:没有影响
        删除一个成员方法(该方法未使用成员变量),向一个函数中多加一句话,以及对使用到成员变量的成员变量进行以上操作
        结果:与上面那个相同
        结论:任意修改一个没有使用成员变量的成员方法无影响
导包:
        把as后面那个dm改成dm1,没有影响
        把文件"序列化与反序列化"改为"序列化与反序列化1",反序列化不行了,找不到模块了,再改回 原来的包名,就有可以了
构造函数:
        给原来的所有v3换成v4,理论上没有真正的改变类,这时:
        1.可以反序列化,但是构造时相同的参数列表,序列化得到的结果却不同
        2.当对原始数据调用使用v4的函数时会报错,'DemoClass' object has no attribute 'v4'
        3.如果我把使用v4的函数注释掉,当还是反序列并且得到化上一步的有该方法的对象,然后调用使用v4的方法,结果无疑报错
'''
原始数据结果=b'\x80\x04\x95\xa6\x00\x00\x00\x00\x00\x00\x00\x8c/\xe5\x82\xa8\xe5\xad\x98\xe9\x97\xae\xe9\xa2\x98.\xe5\xba\x8f\xe5\x88\x97\xe5\x8c\x96\xe4\xb8\x8e\xe5\x8f\x8d\xe5\xba\x8f\xe5\x88\x97\xe5\x8c\x96.DemoClass\x94\x8c\tDemoClass\x94\x93\x94)\x81\x94}\x94(\x8c\x02v1\x94\x8c\x17\xe7\xac\xac\xe4\xb8\x80\xe4\xb8\xaa\xe6\x88\x90\xe5\x91\x98\xe5\x8f\x98\xe9\x87\x8fv1\x94\x8c\x02v2\x94\x8c\x17\xe7\xac\xac\xe4\xb8\x80\xe4\xb8\xaa\xe6\x88\x90\xe5\x91\x98\xe5\x8f\x98\xe9\x87\x8fv2\x94\x8c\x02v3\x94\x8c\x17\xe7\xac\xac\xe4\xb8\x80\xe4\xb8\xaa\xe6\x88\x90\xe5\x91\x98\xe5\x8f\x98\xe9\x87\x8fv3\x94ub.'
#原始数据结果=b'\x80\x04\x95\xa6\x00\x00\x00\x00\x00\x00\x00\x8c/\xe5\x82\xa8\xe5\xad\x98\xe9\x97\xae\xe9\xa2\x98.\xe5\xba\x8f\xe5\x88\x97\xe5\x8c\x96\xe4\xb8\x8e\xe5\x8f\x8d\xe5\xba\x8f\xe5\x88\x97\xe5\x8c\x96.DemoClass\x94\x8c\tDemoClass\x94\x93\x94)\x81\x94}\x94(\x8c\x02v1\x94\x8c\x17\xe7\xac\xac\xe4\xb8\x80\xe4\xb8\xaa\xe6\x88\x90\xe5\x91\x98\xe5\x8f\x98\xe9\x87\x8fv1\x94\x8c\x02v2\x94\x8c\x17\xe7\xac\xac\xe4\xb8\x80\xe4\xb8\xaa\xe6\x88\x90\xe5\x91\x98\xe5\x8f\x98\xe9\x87\x8fv2\x94\x8c\x02v4\x94\x8c\x17\xe7\xac\xac\xe4\xb8\x80\xe4\xb8\xaa\xe6\x88\x90\xe5\x91\x98\xe5\x8f\x98\xe9\x87\x8fv3\x94ub.'


#判断改变前后的同一对象序列化后的结果是否相同
print(result==原始数据结果)

#看最开始序列化后得到的结果用现在的类文件还能不能反序列化
原始对象=pickle.loads(原始数据结果)

#测试此对象是否能使用
原始对象.test1("ss")
#原始对象.showv4()
transient

我猜想序列化只要记录这么几个信息:

1.类的路径(带包名)

2.成员变量(变量名称和变量的值)

并且反序列化的步骤如下:

1.按照储存的类路径找到这个对象的类

2.按照储存的变量名称和变量的值走构造方法创建一个该类的实例.

 

结论是:

只要 1.类路径的写法不变,2.构造方法不变(形参可以变,但是成员变量的名称不能变)

反序列化就一般没有问题.

如果条件限制得更严格一点,

即如果只改变了成员方法,构造时给的参数一样,那么甚至序列化的结果就是一摸一样的.

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值