跨Python文件读取.env时遭遇NoneType错误求助
问题根源
核心问题是导入Bot类的时机早于加载环境变量的时机:main.py中先执行from bot.bot import Bot导入模块,此时bot.py会立即执行内部所有代码(包括os.getenv调用),但load_dotenv()是在导入之后才执行的,导致bot.py读取环境变量时,.env还未被加载,返回None。
解决方案
方案一:调整导入顺序(推荐)
修改main.py,将加载环境变量的代码移到所有依赖环境变量的模块导入之前:
import os from dotenv import load_dotenv # 先加载环境变量,再导入依赖它的模块 load_dotenv() TOKEN = os.getenv('DISCORD_TOKEN') import discord from discord.ext import commands from bot.bot import Bot from logger import logger intents = discord.Intents.all() bot = Bot(command_prefix='!', intents=intents) @bot.event async def on_ready(): logger.info(f'Logged in as {bot.user.name}') @bot.event async def on_message(message): await bot.process_commands(message) bot.run(TOKEN)
方案二:在bot.py中独立加载.env(需处理路径)
如果不想调整导入顺序,可在bot.py中直接加载.env,但需指定项目根目录的.env路径(避免在子目录中找不到文件):
import os from pathlib import Path from dotenv import load_dotenv import subprocess from discord.ext import commands from utils import backup_utils from logger import logger # 定位项目根目录的.env文件 env_path = Path(__file__).parent.parent / '.env' load_dotenv(dotenv_path=env_path) print(os.getenv('TARGET_CHANNEL_ID')) TARGET_CHANNEL_ID = int(os.getenv('TARGET_CHANNEL_ID')) SCRIPT_URL = os.getenv('SCRIPT_URL') BACKUP_ARGUMENTS_FILE = 'backup_arguments.txt'
额外注意事项
.env文件中的变量值无需加引号,dotenv会自动解析,比如写成DISCORD_TOKEN=token而非DISCORD_TOKEN="token",避免读取到带引号的无效字符串。- 确认
.env文件确实在项目根目录,无拼写错误(比如误写为.env.example)。
内容的提问来源于stack exchange,提问作者Joshua Merold
相关产品推荐
相关产品推荐

