如何实例化一个全新的包含列表的临时对象

How to Instantiate a Completely Fresh Temporary Object that Contains Lists

我目前正在使用 Python 来解析 CAN 数据库文件。我 运行 在实施过程中遇到了列表问题,并给了它一个快速补丁使其工作,但它有点丑陋,似乎有更优雅的解决方案。

我已经定义了一个对象 CAN 数据库,其中一种方法采用要解析的文件,其中包含数据库中消息的定义。我遍历文件中的每一行,当我遇到指示消息描述的行时,我创建一个临时变量来引用我为 CAN 消息定义的对象,其中一些成员是列表。我使用基于文件中接下来几行的方法将元素放入这些列表中。

现在当我完成这个临时对象后,我将它添加到 CAN 数据库对象中。由于我不再需要此变量引用的数据,因此我将值 None 分配给它并在下一次迭代中通过检测消息描述符重新实例化干净的平板变量。或者这就是计划。

当我进行下一次迭代并需要使用这个变量时,我向这些列表添加了一些值,发现它们实际上并不为空。似乎尽管将变量分配给引用 None,列表中的值仍然存在并且没有被清理。

您可以在下面看到我的解决方案,即专门堆叠更多方法以摆脱持久列表元素。

以下是文件的一些相关部分:

解析循环

for line in file:
    line = line.rstrip('\n')
    line_number += 1  # keep track of the line number for error reporting

    if line.startswith("BU_:"):
        self._parseTransmittingNodes(line)

    elif line.startswith("BO_"):
        can_msg = self._parseMessageHeader(line).ResetSignals().ResetAttributes()
        building_message = True

    elif line.startswith(" SG_") and building_message:
        can_msg.AddSignal(self._parseSignalEntry(line))
        # can_msg.updateSubscribers()

    elif line == "":
        if building_message:
            building_message = False
            self._messages += [can_msg]
            can_msg = None

重置方法

def ResetSignals(self):
    """
    Flushes all the signals from the CANMessage object.
    """
    self._signals = []
    return self

def ResetAttributes(self):
    """
    Flushes all the attributes from the CANMessage object.
    """
    self._attributes = []
    return self

如何让这个变量每次都成为一个新对象?我是否应该有一个清除所有内部结构的方法,而不是像 C# 中的 IDispose 接口那样分配它 None

编辑:这是 CANMessage 对象的完整来源:

class CANMessage:
    """
    Contains information on a message's ID, length in bytes, transmitting node,
    and the signals it contains.
    """
    _name = ""
    _canID = None
    _idType = None
    _dlc = 0
    _txNode = ""
    _comment = ""
    _signals = list()
    _attributes = list()
    _iter_index = 0
    _subscribers = list()

    def __init__(self, msg_id, msg_name, msg_dlc, msg_tx):
        """
        Constructor.
        """
        self._canID = msg_id
        self._name = msg_name
        self._dlc = msg_dlc
        self._txNode = msg_tx

    def __iter__(self):
        """
        Defined to make the object iterable.
        """
        self._iter_index = 0
        return self

    def __next__(self):
        """
        Defines the next CANSignal object to be returned in an iteration.
        """
        if self._iter_index == len(self._signals):
            self._iter_index = 0
            raise StopIteration
        self._iter_index += 1
        return self._signals[self._iter_index-1]

    def AddSignal(self, signal):
        """
        Takes a CANSignal object and adds it to the list of signals.
        """
        self._signals += [signal]
        return self

    def Signals(self):
        """
        Gets the signals in a CANMessage object.
        """
        return self._signals

    def SetComment(self, comment_str):
        """
        Sets the Comment property for the CANMessage.
        """
        self._comment = comment_str

        return self

    def CANID(self):
        """
        Gets the message's CAN ID.
        """
        return self._canID

    def AddValue(self, value_tuple):
        """
        Adds a enumerated value mapping to the appropriate signal.
        """
        for signal in self:
            if signal.Name() == value_tuple[0]:
                signal.SetValues(value_tuple[2])
                break
        return self

    def AddAttribute(self, attr_tuple):
        """
        Adds an attribute to the message.
        """
        self._attributes.append(attr_tuple)
        return self

    def ResetSignals(self):
        """
        Flushes all the signals from the CANMessage object.
        """
        self._signals = []
        return self

    def ResetAttributes(self):
        """
        Flushes all the attributes from the CANMessage object.
        """
        self._attributes = []
        return self

    def Name(self):
        return self._name

    def TransmittingNode(self):
        return self._txNode

    def DLC(self):
        return self._dlc

您遇到的问题是因为您使用了 class 属性而不是实例属性。如果将未传递给 __init__ 的属性的初始化从 class 范围移动到 __init__,每个实例将有自己的一组列表。
这是它的样子:

class CANMessage:
    """
    Contains information on a message's ID, length in bytes, transmitting node,
    and the signals it contains.
    """

    def __init__(self, msg_id, msg_name, msg_dlc, msg_tx):
        """
        Constructor.
        """
        self._canID = msg_id
        self._name = msg_name
        self._dlc = msg_dlc
        self._txNode = msg_tx
        self._name = ""
        self._canID = None
        self._idType = None
        self._dlc = 0
        self._txNode = ""
        self._comment = ""
        self._signals = list()
        self._attributes = list()
        self._iter_index = 0
        self._subscribers = list()

    # the rest of the class is unchanged, and not repeated here...