1

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

4

2 回答 2

4

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

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

奇怪的是,您的代码以一种迂回的方式突出显示了一个例外……这与描述符有关__slots____slots__将类更改为不再将属性存储在动态字典中,而是存储在静态结构中。请参阅__slots__ 的用法?了解更多信息。

通常,当__slots__定义时,您不能分配给未在__slots__. 所以你可能会问....既然你__slots__为你的课程定义了为什么你没有得到一个AttributeError?答案是__slots__仅适用于“新样式类”请参阅Python 中旧样式和新样式类有什么区别?了解新旧类之间的区别。

如果您定义Packet从基类继承objectclass Packet(object):不是仅仅让它成为一个新样式的类,并且当您尝试分配给时您class Packet()确实会得到一个AttributeErrorItemData

于 2013-10-15T23:08:48.923 回答
2

属性名称是itemData,不是ItemData。如果您更改所有对此的packet3.ItemData引用packet3.itemData应该可以正常工作。

于 2013-10-15T22:49:57.943 回答