2013-10-15 30 views
1

我是Python新手,不明白爲什麼我無法做到這一點。 當我嘗試更改來自父對象的Packet.ItemData中的值時,它不起作用。請參閱代碼中的「不工作」註釋。Python - 無法更改類中項目的值

import json 
from copy import deepcopy 


class Event(): 
    __slots__= 'itemName' 

    def __init__(self, itemName): 
     self.itemName = itemName 


    def encode(self): 
     obj = {} 
     obj['itemName'] = str(self.itemName)    
     return json.dumps(obj) 

    def decode(self, json_Str): 
     obj = json.loads(json_Str) 
     self.itemName = obj['itemName']   



class Packet(): 
    __slots__= 'pID', 'itemData' 

    def __init__(self, pID, itemData): 
     self.pID = pID 
     self.itemData = itemData 

    def encode(self): 
     obj = {} 
     obj['pID'] = int(self.pID) 
     obj['itemData'] = str(self.itemData.encode()) 

     return json.dumps(obj) 

    def decode(self, json_Str): 
     obj = json.loads(json_Str) 
     self.pID = obj['pID'] 
     self.itemData = Event(0,'') 


defaultEvent = Event('Dflt') 
defaultPacket = Packet(1, defaultEvent) 



event2 = Event('NoName') 
print 'event : ', event2.encode() 
packet3 = deepcopy(defaultPacket) 
packet3.ItemData = event2; #direct assign doesn't work 
packet3.ItemData = deepcopy(event2); #deep copy doesn't work 
packet3.ItemData.itemName = 'Hello' #event this doesn't work 
print 'packet : ', packet3.encode() 

我想包裝數據,所以我得到正是我期望從JSON編碼和解碼時。

回答

4

FJ指出的確是正確的...屬性的名稱是itemData而不是ItemData

作爲Python的新手,您可能會認爲錯別字會引發錯誤...類似於「Packet沒有屬性ItemData」,但這種情況不會發生。默認情況下,Python類將屬性存儲在字典中,因此分配給之前不存在的屬性就像向字典中添加新映射一樣。

奇怪的是,你的代碼在迂迴的方式突出顯示了一個例外......這與描述符__slots__有關。 __slots__將該類更改爲不再將屬性存儲在動態字典中,而是將其更改爲靜態結構。有關更多信息,請參閱Usage of __slots__?

通常情況下,當定義了__slots__時,您不能指定在__slots__中未指定的屬性。所以你可能會問....因爲你爲你的課程定義了__slots__爲什麼你沒有得到AttributeError?答案是__slots__只適用於'新式班級'請參閱What is the difference between old style and new style classes in Python?以瞭解新舊班級之間的區別。

假如你定義Packet從基類object繼承像class Packet(object):,而不是僅僅class Packet()一定會成爲一個新的風格類,你會確實得到了AttributeError當你想分配給ItemData

+0

謝謝,我討厭追逐敏感,所以用pascal。我試圖使用插槽來防止額外的數據在那裏。 – runfastman

2

屬性名稱是itemData,而不是ItemData。如果您將所有packet3.ItemData引用更改爲packet3.itemData,則應該正常工作。