Skip to main content
 首页 » 编程设计

Python之无法更改类内项目的值

2025年05月04日20shihaiming

我是 Python 新手,不明白为什么我不能这样做。 当我尝试从父对象更改 Packet.ItemData 中的值时,它不起作用。请参阅代码中的“不起作用”注释。

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 编码和解码时得到我所期望的。

请您参考如下方法:

FJ 指出的确实是正确的...属性的名称是 itemData 而不是 ItemData。

作为 Python 的新手,您可能预料到拼写错误会引发错误……类似于“数据包没有属性 ItemData”,但这并没有发生。 Python 类默认将属性存储在字典中,因此分配给以前不存在的属性就像向字典添加新映射一样。

奇怪的是,您的代码以一种迂回的方式突出显示了一个异常(exception)...并且与描述符 __slots__ 有关。 __slots__ 将类更改为不再将属性存储在动态字典中,而是存储在静态结构中。参见 Usage of __slots__?获取更多信息。

通常,当定义了 __slots__ 时,您不能分配给未在 __slots__ 中指定的属性。所以你可能会问....既然你为你的类定义了 __slots__ 为什么你没有得到一个 AttributeError?答案是 __slots__ 仅适用于“新型类”,请参阅 What is the difference between old style and new style classes in Python?了解新式和旧式类(class)之间的区别。

你是否定义了 Packet 从基类 object 继承,比如 class Packet(object): 而不仅仅是 class Packet () 它会使它成为一个新式类,当您尝试分配给 ItemData

时,您确实会得到一个 AttributeError