2012-06-28 56 views
6

我想定義一個能夠從另一個實例的序列化數據中讀取數據的類。下面是簡化代碼:如何使用pickle()初始化一個實例?

class MyClass(list): 

    def __init__(self,**kwargs): 
     if kwargs.has_key('fdata'): 
      f = open(kwargs['fdata'],'r') 
      self = pickle.load(f) 
      print len(self) #prints 320   
      f.close()    

    ... 

a = MyClass(fdata='data.dat') 
print len(a) #prints 0 

這是輸出我得到:

320 
0 

我的問題是,返回的實例總是空的,即使我能夠讀取裏面的所有元素__init__()什麼可能導致這種情況?

回答

4

勘定到self裏面的方法只需將本地名稱self重新綁定到不同的對象。在Python中對裸名稱的分配決不會修改任何對象 - 它們只是重新綁定名稱。

你爲什麼不使用直線前進

with open("data.dat") as f: 
    a = pickle.load(f) 

,而不是構建一個新的類?如果你不喜歡這個,把它包裝在一個函數中,但是把這段代碼放入__init__()並不是很有用。

還有其他方法可以達到同樣的效果。可能最好的方法來實現你正在嘗試的是覆蓋__new__()而不是__init__() - __new__()被稱爲之前新實例的構建,所以你可以簡單地返回unpickled實例,而不必修改已經構建的實例。

3

self是Python中的常規局部變量。你不能使用self = other使對象「變成」別的東西,你只需重新分配本地。你必須恢復屬性一個接一個,或使用類似:(我還沒有測試的最後一行,這很可能使你的小貓爆炸)

self.__dict__ = pickle.load(f).__dict__ 

+0

指定'__dict__'來複制對象狀態,這是在你從(object)派生的(普通)情況下工作的,並且不要定義__slots__。 –

+1

'self .__ dict __。update()'可能是一個「更安全」的選項,但是你可能會留下一些從醃製數據中刪除的東西,這是有原因的。 –