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

时间:2017-04-17 22:27:12

标签: python list garbage

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

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

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

当我经历下一次迭代并需要使用此变量时,我会向这些列表添加一些值,并发现它们实际上并不是空的。似乎尽管将变量指定为引用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#中的None接口那样分配IDispose

编辑:这是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

1 个答案:

答案 0 :(得分:0)

您看到的问题是因为您使用了类属性而不是实例属性。如果将属性的初始化移动到__init__从类范围到__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...