如果没有在Python中定义变量,那么设置变量的最佳方法是什么?

2024-09-24 22:28:59 发布

您现在位置:Python中文网/ 问答频道 /正文

在我的discord机器人小游戏中,这意味着我无法更改user,因为它是由discord API提供的,玩游戏的人也可以在discord中输入命令,而不在他们的PC上执行python文件。我将用户的数据保存在json文件中,并在需要时将该文件读取到字典中。现在我不必担心KeyError当我尝试从该字典中读取某些内容时,例如如果我尝试读取player_data[user_id]["quests"]["end"]但这不会被定义,我在每个命令开始时调用函数setup,该函数测试用户的数据是否已经保存:

async def setup(user):
    global ITEMS
    with open("player_data.json", "r") as json_file:
        player_data = json.load(json_file)
    try:
        player = player_data[str(user.id)]
    except KeyError:
        player_data[str(user.id)] = {}
        player_data[str(user.id)]["inventory"] = {}
        for item in ITEMS:
            player_data[str(user.id)]["inventory"][item] = 0
        player_data[str(user.id)]["quests"] = {}
        player_data[str(user.id)]["quests"]["completed"] = "0"
        player_data[str(user.id)]["quests"]["running"] = False
        player_data[str(user.id)]["quests"]["start"] = None
        player_data[str(user.id)]["quests"]["end"] = None
        player_data[str(user.id)]["quests"]["duration"] = None
        player_data[str(user.id)]["trees"] = 2
        player_data[str(user.id)]["daily_claim"] = None
    with open("player_data.json", "w") as json_file:
        json.dump(player_data, json_file)

现在这有一个明显的缺陷: 如果定义了player_data[str(user.id)] = {},即使不定义player_data[str(user.id)]["trees"] = 2,也不会引发KeyError。解决这个问题的方法是,如果我对字典中的每一个键都使用try:except,但是这不是很干净,所以我的问题是,有更好的方法吗

我尝试过的


Tags: 文件命令noneidjsondata字典定义
2条回答

听起来好像每次当条目不存在或是空的dict时都要初始化player_data[str(user.id)]

如果是这种情况,我建议使用^{}执行以下操作,如果条目不存在,则返回None

async def setup(user):
    global ITEMS
    with open("player_data.json", "r") as json_file:
        player_data = json.load(json_file)

    user_id = str(user.id)
    if not player_data.get(user_id):
        player_data[user_id] = {
            "inventory": {item: 0 for item in ITEMS}
            "quests" = {
                "completed": "0"
                "running": False
                "start": None
                "end": None
                "duration": None
            }
            "trees": 2
            "daily_claim": None
        }

    with open("player_data.json", "w") as json_file:
        json.dump(player_data, json_file)
class User:
    def __init__(self, id):
        self.id = id

def dict_merge(base_dct, merge_dct, add_keys=True):
    # Source: https://gist.github.com/angstwad/bf22d1822c38a92ec0a9#gistcomment-3077371
    rtn_dct = base_dct.copy()
    if add_keys is False:
        merge_dct = {
            key: merge_dct[key] for key in set(rtn_dct).intersection(set(merge_dct))
        }

    rtn_dct.update(
        {
            key: dict_merge(rtn_dct[key], merge_dct[key], add_keys=add_keys)
            if isinstance(rtn_dct.get(key), dict) and isinstance(merge_dct[key], dict)
            else merge_dct[key]
            for key in merge_dct.keys()
        }
    )
    return rtn_dct

ITEMS = ["item_1", "item_2"]
DEFAULT_PLAYER_DATA = {
    "inventory": {item: 0 for item in ITEMS},
    "quests": {
        "completed": "0",
        "running": False,
        "start": None,
        "end": None,
        "duration": None,
    },
    "trees": 2,
    "daily_claim": None,
}


# In this example I am using a variable instead of a file 
# as reading and saving the json is not part of your problem
player_data_file = {
    "1": {
        "inventory": {
            "item_1": 9999,
        },
        "trees": 9999,
    },
}


def setup(user):
    player_data_from_file = player_data_file.get(str(user.id), {})
    player = dict_merge(DEFAULT_PLAYER_DATA, player_data_from_file)
    player_data_file[str(user.id)] = player
    # This is where you would save the updated player_data_file file/variable
    return player
user = User(1)
print(setup(user))

结果:{'inventory': {'item_1': 9999, 'item_2': 0}, 'quests': {'completed': '0', 'running': False, 'start': None, 'end': None, 'duration': None}, 'trees': 9999, 'daily_claim': None}

user = User(3) # Does not exist in file
print(setup(user))

结果:{'inventory': {'item_1': 0, 'item_2': 0}, 'quests': {'completed': '0', 'running': False, 'start': None, 'end': None, 'duration': None}, 'trees': 2, 'daily_claim': None}

相关问题 更多 >