仅字典队列
Queue of dicts only
我正在编写一个套接字服务器,它在请求时将服务器状态传递给客户端。状态作为 JSON 传递,但在服务器中,数据存储在字典中。当客户端请求服务器状态时,socketserver 处理程序从队列中拉取服务器状态(服务器在线程中运行)。
我的问题是,当我从队列中取出时,我总是只得到最后一个队列条目。当我从队列中提取条目时,我可以看到队列大小在减少。这是一个非常简单的脚本来说明这个问题:
import queue
appState = {"console" : {"message" : "NA"}}
appStateQueue = queue.Queue()
print("Putting dict data on the queue:")
for i in range(10):
appState["console"]["message"] = str(i)
print(appState)
appStateQueue.put_nowait(appState)
print("Queue size:", appStateQueue.qsize())
print("Getting dict data from the queue:")
for i in range(10):
print(appStateQueue.get(), appStateQueue.qsize())
print("Putting integer data on the queue:")
for i in range(10):
appState = i
print(appState)
appStateQueue.put_nowait(appState)
print("Queue size:", appStateQueue.qsize())
print("Getting integer data from the queue:")
for i in range(10):
print(appStateQueue.get(), appStateQueue.qsize())
输出结果如下:
Putting dict data on the queue:
{'console': {'message': '0'}}
{'console': {'message': '1'}}
{'console': {'message': '2'}}
{'console': {'message': '3'}}
{'console': {'message': '4'}}
{'console': {'message': '5'}}
{'console': {'message': '6'}}
{'console': {'message': '7'}}
{'console': {'message': '8'}}
{'console': {'message': '9'}}
Queue size: 10
Getting dict data from the queue:
{'console': {'message': '9'}} 9
{'console': {'message': '9'}} 8
{'console': {'message': '9'}} 7
{'console': {'message': '9'}} 6
{'console': {'message': '9'}} 5
{'console': {'message': '9'}} 4
{'console': {'message': '9'}} 3
{'console': {'message': '9'}} 2
{'console': {'message': '9'}} 1
{'console': {'message': '9'}} 0
Putting integer data on the queue:
0
1
2
3
4
5
6
7
8
9
Queue size: 10
Getting integer data from the queue:
0 9
1 8
2 7
3 6
4 5
5 4
6 3
7 2
8 1
9 0
请注意队列中的字典数据如何始终相同。它总是放在队列中的最后一个数据。整数数据的行为符合我的预期。字符串也可以,虽然我没有在这里显示。
这是怎么回事?
因为,我看到您没有创建新的字典,而只是更改现有字典变量的值。通过下面的代码片段可以很容易地理解这一点,
>>> appState = {"console" : {"message" : "NA"}}
>>> appState
{'console': {'message': 'NA'}}
>>> appState_copy = appState
>>> appState_copy["console"]["message"] = 23
>>> appState
{'console': {'message': 23}}
>>> appState_copy
{'console': {'message': 23}}
Python 仅在将 dict 分配给新变量时复制引用,因此当您在每次迭代中分配整数时,实际上是在更改同一个 dict 的值而不是创建新变量一.
由于您使用的是嵌套字典,因此您需要使用复制模块中的 deepcopy 方法来完成这项工作。
这是一个可行的解决方案:
import queue
import copy #added import statememt
appState = {"console" : {"message" : "NA"}}
appStateQueue = queue.Queue()
print("Putting dict data on the queue:")
for i in range(10):
new_appState = copy.deepcopy(appState) #creating a copy of dict every iteration
new_appState["console"]["message"] = str(i)
print(new_appState)
appStateQueue.put_nowait(new_appState) #putting the created copy in the queue
print("Queue size:", appStateQueue.qsize())
print("Getting dict data from the queue:")
for i in range(10):
print(appStateQueue.get(), appStateQueue.qsize())
print("Putting integer data on the queue:")
for i in range(10):
appState = i
print(appState)
appStateQueue.put_nowait(appState)
print("Queue size:", appStateQueue.qsize())
print("Getting integer data from the queue:")
for i in range(10):
print(appStateQueue.get(), appStateQueue.qsize())
我正在编写一个套接字服务器,它在请求时将服务器状态传递给客户端。状态作为 JSON 传递,但在服务器中,数据存储在字典中。当客户端请求服务器状态时,socketserver 处理程序从队列中拉取服务器状态(服务器在线程中运行)。
我的问题是,当我从队列中取出时,我总是只得到最后一个队列条目。当我从队列中提取条目时,我可以看到队列大小在减少。这是一个非常简单的脚本来说明这个问题:
import queue
appState = {"console" : {"message" : "NA"}}
appStateQueue = queue.Queue()
print("Putting dict data on the queue:")
for i in range(10):
appState["console"]["message"] = str(i)
print(appState)
appStateQueue.put_nowait(appState)
print("Queue size:", appStateQueue.qsize())
print("Getting dict data from the queue:")
for i in range(10):
print(appStateQueue.get(), appStateQueue.qsize())
print("Putting integer data on the queue:")
for i in range(10):
appState = i
print(appState)
appStateQueue.put_nowait(appState)
print("Queue size:", appStateQueue.qsize())
print("Getting integer data from the queue:")
for i in range(10):
print(appStateQueue.get(), appStateQueue.qsize())
输出结果如下:
Putting dict data on the queue:
{'console': {'message': '0'}}
{'console': {'message': '1'}}
{'console': {'message': '2'}}
{'console': {'message': '3'}}
{'console': {'message': '4'}}
{'console': {'message': '5'}}
{'console': {'message': '6'}}
{'console': {'message': '7'}}
{'console': {'message': '8'}}
{'console': {'message': '9'}}
Queue size: 10
Getting dict data from the queue:
{'console': {'message': '9'}} 9
{'console': {'message': '9'}} 8
{'console': {'message': '9'}} 7
{'console': {'message': '9'}} 6
{'console': {'message': '9'}} 5
{'console': {'message': '9'}} 4
{'console': {'message': '9'}} 3
{'console': {'message': '9'}} 2
{'console': {'message': '9'}} 1
{'console': {'message': '9'}} 0
Putting integer data on the queue:
0
1
2
3
4
5
6
7
8
9
Queue size: 10
Getting integer data from the queue:
0 9
1 8
2 7
3 6
4 5
5 4
6 3
7 2
8 1
9 0
请注意队列中的字典数据如何始终相同。它总是放在队列中的最后一个数据。整数数据的行为符合我的预期。字符串也可以,虽然我没有在这里显示。
这是怎么回事?
因为,我看到您没有创建新的字典,而只是更改现有字典变量的值。通过下面的代码片段可以很容易地理解这一点,
>>> appState = {"console" : {"message" : "NA"}}
>>> appState
{'console': {'message': 'NA'}}
>>> appState_copy = appState
>>> appState_copy["console"]["message"] = 23
>>> appState
{'console': {'message': 23}}
>>> appState_copy
{'console': {'message': 23}}
Python 仅在将 dict 分配给新变量时复制引用,因此当您在每次迭代中分配整数时,实际上是在更改同一个 dict 的值而不是创建新变量一.
由于您使用的是嵌套字典,因此您需要使用复制模块中的 deepcopy 方法来完成这项工作。
这是一个可行的解决方案:
import queue
import copy #added import statememt
appState = {"console" : {"message" : "NA"}}
appStateQueue = queue.Queue()
print("Putting dict data on the queue:")
for i in range(10):
new_appState = copy.deepcopy(appState) #creating a copy of dict every iteration
new_appState["console"]["message"] = str(i)
print(new_appState)
appStateQueue.put_nowait(new_appState) #putting the created copy in the queue
print("Queue size:", appStateQueue.qsize())
print("Getting dict data from the queue:")
for i in range(10):
print(appStateQueue.get(), appStateQueue.qsize())
print("Putting integer data on the queue:")
for i in range(10):
appState = i
print(appState)
appStateQueue.put_nowait(appState)
print("Queue size:", appStateQueue.qsize())
print("Getting integer data from the queue:")
for i in range(10):
print(appStateQueue.get(), appStateQueue.qsize())