【问题标题】:Python dict acting inconsistentlyPython dict 行为不一致
【发布时间】:2020-02-12 02:34:00
【问题描述】:

我有一个 python 字典的单个实例作为全局变量。我只在我的代码开始时为其分配一个值。有时dict.get() 返回正确的对象,有时它返回无。我找不到它的模式。

代码是一个等待 HTTP 请求并发送响应的 Web 客户端。我初始化了一个字典,active_games,以保存游戏列表,键是来自服务器的游戏 ID。游戏对象在调用start() 时被添加到字典中,并且在调用end() 之前永远不会被移除。在这两者之间,move() 被多次调用(通常每秒多次)。 move() 中的 print 语句有时会打印正确的字典,有时会打印空字典,然后会引发错误。

以下是代码的相关部分:

import json
import os
import bottle

from api import ping_response, start_response, move_response, end_response
from game import game

# Store all games running on server
active_games = dict()

@bottle.post('/start')
def start():
    global active_games
    data = bottle.request.json
    new_game = game(data["game"]["id"])

    active_games[str(data["game"]["id"])] = new_game

    print(active_games)

    return new_game.start(data)

@bottle.post('/move')
def move():
    global active_games
    data = bottle.request.json

    print(active_games)

    return active_games.get(str(data["game"]["id"])).move(data)

@bottle.post('/end')
def end():
    data = bottle.request.json

    game_ending = active_games.pop(data["game"]["id"])

    return game_ending.end(data)

为什么 dict.get() 不起作用?谢谢你的帮助!如果有帮助,我可以编辑以添加日志和堆栈跟踪

【问题讨论】:

  • 如果您的 Web 应用程序使用多个进程或线程,则不能以这种方式使用全局变量。 Redis 看起来很适合这种用法。
  • 我不熟悉bottle,但我怀疑它正在启动您的代码的多个实例(以便能够处理大量请求)。这些实例中的每一个都有自己的active_games 变量。
  • 为什么你的索引是字符串文字?比如为什么不只使用一个奇异变量?
  • “我有一个 python 字典的单个实例作为全局变量” - 这是灾难的可靠秘诀。
  • 除了上述考虑之外,请注意,当您添加到字典时,您使用str(data["game"]["id"]),但是当您从中弹出时,您使用data["game"]["id"]...为什么不一直使用data["game"]["id"] ?

标签: python dictionary bottle


【解决方案1】:

查看您发布的代码片段,我认为这与start()end() 方法中的global active_games 行有关。

"global 关键字用于从非全局范围创建全局变量,例如在函数内部。" (https://www.w3schools.com/python/ref_keyword_global.asp,最后一次调用于 02.11.2020,w3cschools.com -> Python 教程 -> Python 全局关键字 -> 定义和使用)

但是您不需要在这些函数中声明您的 active_games 字典,因为您已经像这样在脚本的开头声明了它们

# Store all games running on server
active_games = dict()

所以global active_games 所做的只是它覆盖您的 active_games 字典使用同名的空变量,这就是您的 None 返回值的来源。

从你的问题描述来看,这可能不是幕后发生的事情,但你至少可以从代码中删除 global active_games 的任何实例,然后再与我联系

【讨论】:

  • 我最初是这样的,但添加了 global 关键字以防万一。我删除它们并再次尝试,没有区别。两种情况仍然存在同样的问题。在这一点上,我确实认为它与运行多个版本的代码来处理请求有关,但我不知道如何
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-01
  • 2020-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-23
  • 2014-01-18
相关资源
最近更新 更多