Python3.x:如何在类中保存和加载数据
我想要一个类,它在初始化时检查Python3.x:如何在类中保存和加载数据,python,python-3.x,Python,Python 3.x,我想要一个类,它在初始化时检查filename是否存在。如果它这样做了,它应该用文件名初始化自己,否则它应该运行init。稍后,我可以运行save方法,保存整个对象 我想要的东西的草图: class data(object): def __init__(self, filename): if does_not_exist(filename): # create new [... expensive computations]
filename
是否存在。如果它这样做了,它应该用文件名
初始化自己,否则它应该运行init。稍后,我可以运行save
方法,保存整个对象
我想要的东西的草图:
class data(object):
def __init__(self, filename):
if does_not_exist(filename): # create new
[... expensive computations]
self.save(filename)
else: # load existing
with open(filename,'rb') as fp:
self = pickle.load(fp)
def save(self, filename):
with open(filename,'wb') as fp:
pickle.dump(self, fp)
加载时,我知道我可以执行以下操作
tmp = pickle.load(fp)
self.a = tmp.a
self.b = tmb.b
...
但我希望有更好的办法
我假设以前有人问过这个问题,但找不到:/在
\uuuu init\uuuu
中分配给self
是没有意义的,因为您没有修改self
指向的对象——您只是将函数中的变量名self
绑定到另一个对象
您可以使用staticmethod
或classmethod
从缓存执行可选加载:
class Data(object):
@classmethod
def init_cached(cls, filename):
if not os.path.exists(filename): # create new
result = cls(filename)
result.save(filename)
return result
else:
with open(filename, 'rb') as fp:
return pickle.load(fp)
def __init__(self, filename):
pass # [... expensive computations]
现在,使用Data.init\u cached()
而不是Data()
来初始化对象
一种更奇特的方法是覆盖
数据。\uuuu new\uuu()
以实现同样的效果,但使用数据()进行初始化时,会透明地检查缓存版本是否存在:
class Data(object):
def __new__(cls, filename):
if not os.path.exists(filename): # create new
return super(Data, cls).__new__(cls, filename, _save=True)
else:
with open(filename, 'rb') as fp:
return pickle.load(fp)
def __init__(self, filename, _save=False):
# [... expensive computations]
if _save:
self.save(filename)
进一步阅读:在\uuu init\uuu
中分配给self
是没有意义的,因为您没有修改self
指向的对象——您只是将函数中的变量名self
绑定到另一个对象
您可以使用staticmethod
或classmethod
从缓存执行可选加载:
class Data(object):
@classmethod
def init_cached(cls, filename):
if not os.path.exists(filename): # create new
result = cls(filename)
result.save(filename)
return result
else:
with open(filename, 'rb') as fp:
return pickle.load(fp)
def __init__(self, filename):
pass # [... expensive computations]
现在,使用Data.init\u cached()
而不是Data()
来初始化对象
一种更奇特的方法是覆盖数据。\uuuu new\uuu()
以实现同样的效果,但使用数据()进行初始化时,会透明地检查缓存版本是否存在:
class Data(object):
def __new__(cls, filename):
if not os.path.exists(filename): # create new
return super(Data, cls).__new__(cls, filename, _save=True)
else:
with open(filename, 'rb') as fp:
return pickle.load(fp)
def __init__(self, filename, _save=False):
# [... expensive computations]
if _save:
self.save(filename)
进一步阅读:为什么要对整个对象进行酸洗?只Pickle您需要的存储数据-您已经加载了结构,因此尝试将其与数据一起保存没有任何意义。同意。我只是不知道如何以简洁的方式存储所有数据。我更愿意不必为数据对象写东西。我该怎么做呢?您可以使用\uuuuu setstate\uuuu
只对相关数据进行pickle,然后使用\uuuu getstate\uuuuu
魔术方法将其加载回。它不仅使您能够更好地控制如何保存和恢复与实例相关的数据,而且还使pickle不太容易出错(意外的类覆盖等)。参见第三个示例:为什么要对整个对象进行酸洗?只Pickle您需要的存储数据-您已经加载了结构,因此尝试将其与数据一起保存没有任何意义。同意。我只是不知道如何以简洁的方式存储所有数据。我更愿意不必为数据对象写东西。我该怎么做呢?您可以使用\uuuuu setstate\uuuu
只对相关数据进行pickle,然后使用\uuuu getstate\uuuuu
魔术方法将其加载回。它不仅使您能够更好地控制如何保存和恢复与实例相关的数据,而且还使pickle不太容易出错(意外的类覆盖等)。参见第三个示例: