2017-05-14 35 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__()?的詳細信息和參考文獻)