【发布时间】:2022-12-11 01:24:08
【问题描述】:
我在课堂上遇到了关于字典的挑战。我确定我正在监督某事,但我不确定具体是什么。情况如下:
我有一个名为NetMessageHandler 的类,它具有函数onmessage() 和rcvtcpmsg()。
函数onmessage() 允许其他类挂接到使用回调接收的特定网络消息,rcvtcpmsg() 由 TCP 客户端调用以将接收到的原始消息处理为 JSON 并通过系统传递。最后,_run_callbacks() 在收到消息时被调用。
当我调用onmessage() 时,回调存储在类中的字典中。当我在添加内容后打印()字典时,结果符合预期,例如:
{'systemdescription': [<function system_description_handler at 0x7f70a57ee0>]}
Length: 1
但是,当我真的想使用存储的回调进行回调时,字典突然为空,函数失败。我不知道这是怎么发生的,因为我没有清除/设置字典为新值。似乎在 onmessage() 函数完成后,字典被清空了。
{}
Length: 0
到目前为止,我的课程代码如下(仅相关部分):
class NetMessageHandler():
def __init__(self):
# Create an empty dictionary to store
self._callbacks = {}
def _run_callbacks(self, type: str, data: dict[str, Any], origin: NetMessageOrigin):
'''Runs when a message is received'''
print(f'{self.__class__.__name__}: Running callbacks for {type}')
print(self._callbacks) # Added as a test, it returns an empty dictionary: '{}'
# This part never runs as the dictionary is empty
if type in self._callbacks:
for c in self._callbacks[type]:
c(type, data, origin)
def rcvtcpmsg(self, msg: str, origin: 'TCPClient') -> None:
'''Receive a TCP message and parse it to valid JSON, then run callbacks.'''
data = self._parseMessage(msg)
# Create an origin that represents the message sender
origin = NetMessageOrigin(NetMessageOriginType.TCP, origin)
# Run callbacks for the specific message type
if "t" in data:
self._run_callbacks(data["t"], data, origin)
def onmessage(self, type:str, callback:Callable[[str, dict[str, Any], NetMessageOrigin], Any]):
'''Adds a new callback for a specific message type.'''
# Check if a callback for this message already exists
if type not in self._callbacks:
print(f'{self.__class__.__name__}: New callback array created for "{type}"')
self._callbacks[type] = []
if callback not in self._callbacks[type]:
self._callbacks[type].append(callback)
print(f'{self.__class__.__name__}: Callback added for message type "{type}"')
else:
print(f'{self.__class__.__name__}: Callback already existed for message type "{type}"')
# The prints below output the expected value: {'systemdescription': [<function system_description_handler at 0x7f70a57ee0>]}
print(self._callbacks)
print("Length:", len(self._callbacks))
我检查了一切的顺序,回调是在第一条消息到达之前创建的,这里会发生什么?
【问题讨论】:
-
我看不出有什么可疑之处。您应该检查是否触摸了显示代码“_callbacks”之外的任何地方。
-
我犯了一个非常简单的错误,使用了两个单独的 NetMessageHandler 实例,在其余代码中循环。在一个实例中设置了回调,在另一个实例上调用了 rcvtcpmsg()。这个问题算是解决了,感谢您的回复!
-
@Stathis91 我怀疑可能是这种情况,并且已经开始写一个关于如何验证它并避免这种情况的答案。验证部分似乎不再相关,但让我知道是否值得完成和发布。
-
知道将来如何避免此类情况肯定会很有用,所以如果您已经在准备一些东西,我绝对认为分享会很有用,谢谢!
标签: python