ZetCode

Python os.getenv 函数

上次修改时间:2025 年 4 月 11 日

本综合指南探讨了 Python 的 os.getenv 函数,该函数用于检索环境变量。我们将介绍基本用法、默认值、类型转换和实际配置示例。

基本定义

os.getenv 函数检索环境变量的值。如果变量不存在,它将返回 None,除非指定了默认值。

主要参数:key(变量名),default(如果未找到,则可选返回)。返回字符串值或默认值。适用于 Unix 和 Windows 系统。

基本环境变量访问

os.getenv 的最简单用法是检索变量的值。此示例展示了访问常见的系统环境变量。

basic_access.py
import os

# Get common environment variables
home_dir = os.getenv("HOME")
username = os.getenv("USER")
path_var = os.getenv("PATH")

print(f"Home directory: {home_dir}")
print(f"Username: {username}")
print(f"PATH contains: {path_var.split(':')[:3]}...")

# Non-existent variable
missing_var = os.getenv("NON_EXISTENT_VAR")
print(f"Missing variable returns: {missing_var}")

此示例检索常见的 Unix 环境变量。PATH 变量被拆分以显示部分内容。不存在的变量返回 None。

环境变量通常是字符串。可用的确切变量取决于操作系统和用户配置。

提供默认值

default 参数允许在变量未设置时指定备用值。这可以防止返回 None 并简化配置处理。

default_values.py
import os

# Configuration with defaults
db_host = os.getenv("DB_HOST", "localhost")
db_port = os.getenv("DB_PORT", "5432")
debug_mode = os.getenv("DEBUG", "False")

print(f"Database connection: {db_host}:{db_port}")
print(f"Debug mode enabled: {debug_mode}")

# Nested defaults example
max_retries = os.getenv("MAX_RETRIES", 
                       os.getenv("DEFAULT_RETRIES", "3"))
print(f"Maximum retries: {max_retries}")

这显示了配置参数的默认值的设置。嵌套示例在采用硬编码默认值之前检查多个备用选项。

当环境配置不完整或缺失时,默认值有助于使应用程序更健壮。

值类型转换

环境变量始终是字符串。此示例演示了如何将它们转换为适合应用程序使用的 Python 类型。

type_conversion.py
import os

# String to integer conversion
port = os.getenv("PORT", "8080")
try:
    port = int(port)
except ValueError:
    port = 8080

# String to boolean conversion
debug = os.getenv("DEBUG", "false").lower()
debug = debug in ("true", "1", "yes", "y")

# String to list conversion
allowed_hosts = os.getenv("ALLOWED_HOSTS", "localhost,127.0.0.1")
allowed_hosts = [h.strip() for h in allowed_hosts.split(",")]

print(f"Port: {port} (type: {type(port)})")
print(f"Debug: {debug} (type: {type(debug)})")
print(f"Allowed hosts: {allowed_hosts} (type: {type(allowed_hosts)})")

这展示了环境变量的常见类型转换模式。演示了整数、布尔值和列表转换,并带有错误处理。

正确的类型转换可确保配置值在应用程序逻辑中正常工作。

配置类示例

一种常见的模式是将环境变量包装在配置类中。这提供了类型安全并集中了配置管理。

config_class.py
import os
from dataclasses import dataclass

@dataclass
class AppConfig:
    db_host: str
    db_port: int
    debug: bool
    timeout: float

    @classmethod
    def from_env(cls):
        return cls(
            db_host=os.getenv("DB_HOST", "localhost"),
            db_port=int(os.getenv("DB_PORT", "5432")),
            debug=os.getenv("DEBUG", "false").lower() in ("true", "1"),
            timeout=float(os.getenv("TIMEOUT", "5.0"))
        )

# Load configuration
config = AppConfig.from_env()
print(f"Database: {config.db_host}:{config.db_port}")
print(f"Debug mode: {config.debug}")
print(f"Timeout: {config.timeout} seconds")

此示例使用 dataclass 来存储类型化的配置。from_env 类方法处理环境变量的加载和转换。

配置类模式通过集中环境变量处理使应用程序更易于维护。

Django 风格的设置管理

此示例演示了一种 Django 风格的设置模式,其中环境变量会覆盖模块中的默认设置。

django_style.py
import os
from typing import Any

def get_setting(name: str, default: Any = None, cast: type = str) -> Any:
    value = os.getenv(name)
    if value is None:
        return default
    try:
        return cast(value)
    except (ValueError, TypeError):
        return default

# Application settings
DEBUG = get_setting("DEBUG", False, bool)
DATABASE_URL = get_setting("DATABASE_URL", "sqlite:///db.sqlite3")
ALLOWED_HOSTS = get_setting("ALLOWED_HOSTS", ["localhost"], 
                           lambda x: [h.strip() for h in x.split(",")])
MAX_UPLOAD_SIZE = get_setting("MAX_UPLOAD_MB", 10, int) * 1024 * 1024

print(f"Debug mode: {DEBUG}")
print(f"Database URL: {DATABASE_URL}")
print(f"Allowed hosts: {ALLOWED_HOSTS}")
print(f"Max upload size: {MAX_UPLOAD_SIZE} bytes")

get_setting 辅助函数提供了灵活的配置加载和类型转换。复杂的转换使用 lambda 函数。

此模式是可扩展的,并且适用于具有许多配置选项的应用程序。

测试环境变量

此示例展示了如何在测试期间通过临时修改环境来测试使用 os.getenv 的代码。

testing_env.py
import os
from unittest import TestCase, mock

def get_config():
    return {
        "api_key": os.getenv("API_KEY", "default_key"),
        "endpoint": os.getenv("API_ENDPOINT", "https://api.example.com")
    }

class TestEnvironmentConfig(TestCase):
    @mock.patch.dict(os.environ, {
        "API_KEY": "test_key",
        "API_ENDPOINT": "https://:8000"
    })
    def test_with_mocked_env(self):
        config = get_config()
        self.assertEqual(config["api_key"], "test_key")
        self.assertEqual(config["endpoint"], "https://:8000")

    def test_with_defaults(self):
        with mock.patch.dict(os.environ, clear=True):
            config = get_config()
            self.assertEqual(config["api_key"], "default_key")
            self.assertEqual(config["endpoint"], "https://api.example.com")

if __name__ == "__main__":
    import unittest
    unittest.main()

该测试使用 unittest.mock.patch.dict 来临时修改 os.environ。这允许测试自定义值和默认回退。

正确的测试可确保环境变量处理在不同的部署场景中正常工作。

安全注意事项

最佳实践

资料来源

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直在撰写编程文章。到目前为止,我已经撰写了超过 1,400 篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 Python 教程