You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何区分并拆分os.environ为默认环境变量与自定义变量?

问题

能否将os.environ拆分为默认环境变量与自定义添加的变量?比如用集合语法计算自定义变量的键:

custom_addon_env_var_keys = set(os.environ.keys()) - set(os.environ.default.keys()) # 是否存在类似os.environ.default的属性?

有没有类似os.environ.default的方式,在程序启动后获取纯净的环境变量(排除程序启动后添加的所有自定义键)?

我查看了os模块的源码,environ由_createenviron函数初始化,但该函数在environ初始化后就被删除了,无法重新初始化一个environ_2来实现需求,复制整个初始化函数又显得笨拙。

下面的代码展示了期望的行为,但因为我要把它用于跨文件变量,所以无法在启动时保存原始副本:

import os

# 因用于跨文件变量,无法在启动时保存原始副本
ORIGINAL_ENV_COPY = os.environ.copy()

os.environ["MY_CUSTOM_ENV_KEY"] = "HelloWorld"

# ORIGINAL_ENV_COPY应是获取os.environ原始版本的方式
custom_addon_env_var_keys = set(os.environ.keys()) - set(ORIGINAL_ENV_COPY.keys())

print(custom_addon_env_var_keys) # 输出: {"MY_CUSTOM_ENV_KEY"}

补充说明

我有一个名为environment.py的文件用于初始化常量,它会和main.py一起打包成二进制可执行文件,部分代码如下:

import os
import random
import sys

os.environ["TIMEZONE"] = "Asia/Taipei"

os.environ["PROJECT_NAME"] = "Project name"

os.environ["APP_USER_MODEL_ID"] = f"{os.environ['PROJECT_NAME']}.App.User.Model.Id"

os.environ["SERVER_URL"] = f"https://www.my.server.io/projects/{os.environ['PROJECT_NAME']}"
os.environ["STORAGE_URL"] = f"https://www.my.server.io/projects/{os.environ['PROJECT_NAME']}/Storage"
os.environ["MODULES_URL"] = f"https://www.my.server.io/projects/{os.environ['PROJECT_NAME']}/Modules"

os.environ["USER_AGENT"] = random.choice([
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) Gecko/20100101 Firefox/61.0",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36",
    "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)",
    "Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.5; en-US; rv:1.9.2.15) Gecko/20110303 Firefox/3.6.15"
])

if getattr(sys, "frozen", False):
    sys.argv = [arg for arg in sys.argv if not arg.startswith("-")]
    os.environ["EXECUTABLE_ROOT"] = os.path.dirname(sys.executable)
else:
    os.environ["EXECUTABLE_ROOT"] = os.path.dirname(os.path.abspath(sys.modules["__main__"].__file__))

为何要将变量和常量存入os.environ?

  • environment.py会和main.py一起打包成二进制可执行文件,其他模块不知道该文件的存在(只剩main.exe);
  • 部分变量如USER_AGENT、EXECUTABLE_ROOT代码量较大,存入可避免重复代码。

为何需要获取自定义环境变量键?

因为我将变量存入其中,收到崩溃报告时需调试是否由这些变量导致问题。例如USER_AGENT,若其中某个不可用,我需要知道是哪个引发错误并将其移除,而非逐个测试。且默认环境变量键众多,全部发送会杂乱,我只需自己添加的键。

解决方案(感谢@zondo)

使用setattr将原始os.environ保存到os模块下,并通过if语句避免重新导入时覆盖原始保存:

import os

# 首次运行时不存在default_environ属性
if not hasattr(os, "default_environ"):
    setattr(os, "default_environ", os.environ.copy())

# ... 其他变量初始化代码

内容的提问来源于stack exchange,提问作者Head Cracked

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 17:14:55