Python跨脚本调用函数内变量报nom未定义如何解决
问题根因
报错"nom" is not defined核心是Python全局变量作用域的用法错误:
- 你在
enregistrement.py顶层写的global声明是无效的,global关键字只能在函数内部使用,作用是标记变量为模块级全局变量,顶层声明没有任何实际效果 - 你在
loadfiche()函数内部给argent_fiche、nom这些变量赋值时,没有提前声明它们是全局变量,所以这些变量全都是loadfiche函数的局部变量,函数运行结束就会被销毁,根本不会暴露到模块全局作用域,main.py导入时自然拿不到这些值 - 你虽然最后组装了
fiche_joueur字典,但main.py里根本没从这个字典里取值,还是直接调用不存在的全局变量nom、argent_fiche等,最终触发未定义错误
修复方案
优先选第一种方案,逻辑清晰且不会出现异步并发问题。
方案1:让loadfiche直接返回玩家数据字典(推荐)
这种写法完全不依赖全局变量,从根源上避免作用域混乱,也适配discord机器人的异步运行场景。
第一步:修改enregistrement.py
import pickle def loadfiche(identifiant): # 上下文管理器自动处理文件关闭,不用手动写close with open(f"fiche de {identifiant}", "rb") as fiche_open: fiche_load = pickle.load(fiche_open) # 直接组装字典返回,用字符串当key可读性更强 fiche_joueur = { "argent_fiche": fiche_load[1], "argent_poche": fiche_load[2], "royaume_pari": fiche_load[3], "argent_pari": fiche_load[4], "exploit": fiche_load[5], "role": fiche_load[6], "nom": fiche_load[7], "couleur": fiche_load[8], "souterrain": fiche_load[9], "aerien": fiche_load[10], "paris_faits": fiche_load[11], "pari_gagnes": fiche_load[12], "moyenne_pari": fiche_load[13], "inventaire": fiche_load[14], "pari_recupere": fiche_load[15] } return fiche_joueur
第二步:修改main.py的fiche命令逻辑
# 删掉没用的导入:from turtle import color,turtle是桌面绘图库和discord机器人无关 import discord import asyncio from discord.ext import commands from discord.utils import get import random import datetime import time import pickle from enregistrement import * @bot.command() async def fiche(ctx,*, membre : discord.Member=None): # 不要用特殊字符'∅'当默认值,discord.py的对象参数默认值用None才符合规范 if membre is not None: user = membre.id # 2.0以上版本discord.py的avatar_url已经改为avatar.url pfp = membre.avatar.url else: user = ctx.author.id pfp = ctx.author.avatar.url # 直接接收函数返回的玩家数据,从字典取值,不依赖全局变量 fiche_joueur = loadfiche(user) nom = fiche_joueur["nom"] argent_fiche = fiche_joueur["argent_fiche"] argent_poche = fiche_joueur["argent_poche"] exploit = fiche_joueur["exploit"] royaume_pari = fiche_joueur["royaume_pari"] argent_pari = fiche_joueur["argent_pari"] role = fiche_joueur["role"] embed = discord.Embed(title = None, description = None,color = 0x7289da) embed.set_author(name=nom, icon_url = pfp) embed.set_thumbnail(url = "random URL") embed.add_field(name = ":credit_card: | Argent en banque", value = argent_fiche ,inline = False) embed.add_field(name = ":dollar: | Argent en poche", value = argent_poche, inline = False) embed.add_field(name = ":four_leaf_clover: | Nombre d'exploit", value = exploit,inline = False) embed.add_field(name = ":arrows_counterclockwise: | Pari en cours", value = royaume_pari,inline = False) embed.add_field(name = ":chart_with_upwards_trend: | Montant parié", value = argent_pari,inline = False) embed.add_field(name = rang[role], value = emote_rang[role],inline = False) embed.set_footer(text = ctx.author.id) await ctx.send(embed = embed)
方案2:强制使用全局变量(不推荐)
如果一定要保留全局变量写法,必须在函数内部给每个变量加global声明,但这种写法在异步场景下如果多个用户同时调用命令,全局变量会被互相覆盖,导致返回的玩家数据错乱。
修改后的enregistrement.py代码如下:
import pickle # 先定义模块级全局变量 argent_fiche = argent_poche = royaume_pari = argent_pari = exploit = role = nom = couleur = souterrain = aerien = paris_faits = pari_gagnes = moyenne_pari = inventaire = pari_recupere = fiche_joueur = None def loadfiche(identifiant): # 必须在函数内部声明所有要修改的全局变量 global argent_fiche, argent_poche, royaume_pari, argent_pari, exploit, role, nom, couleur, souterrain, aerien, paris_faits, pari_gagnes, moyenne_pari, inventaire, pari_recupere, fiche_joueur with open(f"fiche de {identifiant}","rb") as fiche_open: fiche_load = pickle.load(fiche_open) argent_fiche = fiche_load[1] argent_poche = fiche_load[2] royaume_pari = fiche_load[3] argent_pari = fiche_load[4] exploit = fiche_load[5] role = fiche_load[6] nom = fiche_load[7] couleur = fiche_load[8] souterrain = fiche_load[9] aerien = fiche_load[10] paris_faits = fiche_load[11] pari_gagnes = fiche_load[12] moyenne_pari = fiche_load[13] inventaire = fiche_load[14] pari_recupere = fiche_load[15] fiche_joueur = {1 : argent_fiche, 2 : argent_poche, 3 : royaume_pari, 4 : argent_pari, 5 : exploit, 6 : role, 7 : nom, 8 : couleur, 9 : souterrain, 10 : aerien, 11 : paris_faits, 12 : pari_gagnes, 13 : moyenne_pari, 14 : inventaire, 15 : pari_recupere}
内容的提问来源于stack exchange,提问作者furie_noire
相关产品推荐
相关产品推荐

