2017-05-14 41 views
1

我有一个类,我想根据参数以几种方式实例化对象。当我将文件路径传递给函数__init__时,它应该从保存为pickle文件的对象中恢复所有参数。有没有什么聪明的办法来做到这一点,像self=load(...)在__init__函数中初始化pickle中的对象

+0

请[编辑]你的问题,至少是增加一个例子'class'定义。 – martineau

回答

4

__init__做你__init__只口罩self=load(...)当地self变量,它不会更改的实例。

您可以改为在该类的__new__方法中控制新实例的创建。

import pickle 

class Pretty(object): 
    def __new__(cls, filepath=None, *args, **kwargs): 
     if filepath: 
      with open(filepath) as f: 
       inst = pickle.load(f) 
      if not isinstance(inst, cls): 
       raise TypeError('Unpickled object is not of type {}'.format(cls)) 
     else: 
      inst = super(Pretty, cls).__new__(cls, *args, **kwargs) 
     return inst 

你可以做拆封对象,以确保它实际上是你的类的实例的快速实例检查,否则,你可以期待的不良行为,如你的类的__init__方法没有被调用。

1

正如另一个答案中所述,self = load(...)只替换本地变量self。相同的答案建议诉诸类的工作方法,但在Python中不是一个好习惯,因为重写此方法只能用于不可变类型。

相反,你应该使用一个factory,可在这种情况下是一个简单的函数:

def foo_factory(filename=None, *args, **kwargs): 
    if filename: 
     foo_factory.foo = pickle.load(filename) 
    else: 
     foo_factory.foo = Foo(*args, **kwargs) 
    return foo_factory.foo 

,我们假设类Foo是阶级的利益。

(见Why is __init__() always called after __new__()?的详细信息和参考文献)