当我实例化我编写的特定类时,我给它命名并将几个属性作为__init__
的参数。鉴于传递的名称,我的__init__
尝试在磁盘上找到适用于该名称的文件,而不是处理传递的其他参数,而是从文件中读取所有这些文件。如果找不到该文件,则使用参数。
现在我想知道,如果我想使用pickle
存储整个对象而不是使用我自己的例程来编写文件,我将如何完成加载?我无法在__init__
内取消对象,因为已经创建了对象,对吧?
我的一个想法是编写一个我将用于实例化的类方法,如果它存储在磁盘上则返回一个unpickled对象,否则它将使用传递的参数创建一个新对象。
另一个想法是使用__new__
而不是将返回对象的类方法,但我不知道这是否是__new__
的预期用途。
这些想法是否有用或是否有更好的方法来实现这一目标?
答案 0 :(得分:4)
使用工厂功能,而不是在__init__
中执行此操作。例如:
class Foo(object):
# whatever
def get_foo(path, *args, **kwargs):
try:
obj = pickle.load(open(path))
if not isinstance(obj, Foo):
raise TypeError, "%s does not contain a Foo" % path
return obj
except IOError as e:
if e[0] == errno.ENOENT:
return Foo(*args, **kwargs)
else:
raise
答案 1 :(得分:0)
我非常喜欢使用类方法来处理这种事情,因为它将特殊情况逻辑与“标准”类初始化逻辑分开。例如。
class MyClass(object):
@classmethod
def load(cls, name, **kargs):
try:
state = state_from_file(name) ## your loading code
except Exception:
state = kargs
return cls(name, **state)
def __init__(self, name, food=None, **kargs):
self.name = name
self.food = food
d = MyClass(name='eric', food='spam & eggs')
d = MyClass.load(name='eric', food='spam & eggs')
至于如何坚持你的对象状态......我真的不喜欢使用泡菜;毫无疑问它可行但我发现使用json,yaml等格式显式保存您的实例状态更容易。在平台兼容性,未来校对等方面感觉更安全。无论如何。如果您充分隔离了持久性代码,则可以轻松地将其交换出来。