如何实例化一个全新的包含列表的临时对象
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...
我目前正在使用 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...