python pickle 保存和加载私有变量

1 投票
2 回答
1210 浏览
提问于 2025-04-18 06:07

我想保护一个类里的变量。但是如果这个类支持保存和加载功能,那该怎么办呢?

import numpy as np
import pickle
class data(object):
    def __init__(self):
        self.__a = range(100)

    @property    
    def a(self):
         return self.__a

    def save(self, path):
        pickle.dump(self,open(path, 'wb'), protocol=2)

    def load(self, path):
        obj = pickle.load(open(path, 'wb'))
        self.__a = obj.a

这很简单,但__a这个属性就不再受保护了,因为调用instance.a会直接返回instance.__a这个列表,而这个列表可以在外部被修改,这在我的情况下是很危险的。

有没有什么办法可以解决这个问题呢?

2 个回答

0

与其使用不标准的保存/加载方法,不如直接用标准的Python方式来处理对象的保存和加载,也就是直接使用pickle.dump和pickle.load。

在加载后,数据成员的保护状态和之前保存时是一样的,也就是说,你的对象表现得没有变化。

class data(object):
    def __init__(self):
        self.__a = range(100)
    @property    
    def a(self):
         return self.__a

obj = data()
# when you want to save, do:
x = pickle.dumps(obj)
# and for loading, do:
obj = pickle.loads(x)
obj.__dict__
=> {'_data__a': [0,
  1,
  2,
  3,
  ...
]} 

这种方法有很多好处,比如你可以安全地保存那些引用了你类的实例的对象data

1

为了防止列表被修改,你可以通过你的属性返回一个列表的副本:

@property
def a(self):
    return list(self.__a)

撰写回答