导航菜单

  • 1.vector
  • 2.milvus
  • 3.pymilvus
  • 4.rag
  • 5.rag_measure
  • ragflow
  • heapq
  • HNSW
  • cosine_similarity
  • math
  • typing
  • etcd
  • minio
  • collections
  • jieba
  • random
  • beautifulsoup4
  • chromadb
  • sentence_transformers
  • numpy
  • lxml
  • openpyxl
  • PyMuPDF
  • python-docx
  • requests
  • python-pptx
  • text_splitter
  • all-MiniLM-L6-v2
  • openai
  • llm
  • BPETokenizer
  • Flask
  • RAGAS
  • BagofWords
  • langchain
  • Pydantic
  • abc
  • faiss
  • MMR
  • scikit-learn
  • Runnable
  • PromptEngineering
  • dataclasses
  • LaTeX
  • rank_bm25
  • TF-IDF
  • asyncio
  • sqlalchemy
  • fastapi
  • Starlette
  • uvicorn
  • argparse
  • Generic
  • ssl
  • urllib
  • python-dotenv
  • RRF
  • CrossEncoder
  • Lost-in-the-middle
  • Jinja2
  • logger
  • io
  • venv
  • concurrent
  • parameter
  • SSE
  • 1. python-dotenv 是什么?
    • 1.1 为什么需要 python-dotenv?
    • 1.2 基本概念
  • 2. 前置知识
    • 2.1 什么是环境变量?
    • 2.2 什么是 .env 文件?
    • 2.3 Python 基础
  • 3. 安装
    • 3.1 安装 python-dotenv
    • 3.2 验证安装
  • 4. .env 文件格式
    • 4.1 基本语法
    • 4.2 实际项目示例
  • 5. 基本使用
    • 5.1 最简单的用法
    • 5.2 指定 .env 文件路径
    • 5.3 配置选项
  • 6. 常用功能
    • 6.1 获取环境变量(带默认值)
    • 6.2 类型转换
    • 6.3 辅助函数
    • 6.4 直接获取所有变量(不修改 os.environ)
  • 7. 实际应用示例
    • 7.1 简单的配置管理
    • 7.2 配置验证
  • 8. 最佳实践
    • 8.1 项目结构
    • 8.2 创建 .env.example
    • 8.3 .gitignore 配置
  • 9. 常见问题
    • 9.1 .env 文件未找到
    • 9.2 环境变量未加载
    • 9.3 环境变量值为 None
  • 10. 总结
    • 10.1 核心概念回顾
    • 10.2 基本使用流程
    • 10.3 使用 python-dotenv 的好处

1. python-dotenv 是什么? #

python-dotenv 是 Python 中用于管理环境变量的工具,它允许你从 .env 文件加载环境变量到 os.environ 中,让配置管理更简单、更安全。

1.1 为什么需要 python-dotenv? #

在开发应用时,经常需要存储敏感信息(如数据库密码、API 密钥等)。如果直接写在代码中,会有以下问题:

  1. 安全问题:代码可能被提交到版本控制系统,泄露敏感信息
  2. 环境差异:开发、测试、生产环境需要不同的配置
  3. 管理困难:修改配置需要改代码,容易出错

使用 python-dotenv 的好处:

  • 安全:敏感信息存储在 .env 文件中,不提交到版本控制
  • 灵活:不同环境可以使用不同的 .env 文件
  • 简单:一行代码就能加载所有配置

简单理解:

  • 环境变量:存储在系统或文件中的配置信息
  • .env 文件:存储环境变量的文本文件
  • python-dotenv:从 .env 文件读取环境变量的工具

1.2 基本概念 #

# 导入 python-dotenv
from dotenv import load_dotenv
import os

# 加载 .env 文件中的环境变量
load_dotenv()

# 现在可以使用环境变量
api_key = os.getenv('API_KEY')
print(f"API Key: {api_key}")

说明:

  • load_dotenv() 从 .env 文件加载环境变量
  • os.getenv() 获取环境变量的值
  • 环境变量会被加载到 os.environ 中

2. 前置知识 #

在学习 python-dotenv 之前,你需要了解以下基础知识。

2.1 什么是环境变量? #

环境变量(Environment Variables) 是存储在操作系统中的键值对,用于配置应用程序。

简单理解:

  • 环境变量就像是一个全局的配置字典
  • 键(Key)是变量名,值(Value)是变量值
  • 程序可以从环境变量中读取配置

在 Python 中使用环境变量:

# 导入 os 模块
import os

# 获取环境变量
# getenv() 获取环境变量的值,如果不存在返回 None
api_key = os.getenv('API_KEY')

# 获取环境变量(带默认值)
# 如果环境变量不存在,返回默认值
port = os.getenv('PORT', '8000')

# 直接访问 os.environ(字典格式)
# 如果环境变量不存在,会抛出 KeyError
database_url = os.environ['DATABASE_URL']

2.2 什么是 .env 文件? #

.env 文件是一个文本文件,用于存储环境变量。通常放在项目根目录。

简单理解:

  • .env 文件是一个配置文件
  • 每行一个环境变量,格式:KEY=value
  • 以 # 开头的是注释

示例 .env 文件:

# 这是注释
API_KEY=sk-1234567890abcdef
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
DEBUG=True
PORT=8000

2.3 Python 基础 #

你需要了解:

  • 基本的 Python 语法
  • os 模块的使用(os.getenv()、os.environ)
  • 文件操作(读取文件)

3. 安装 #

3.1 安装 python-dotenv #

使用 pip 安装:

# 使用 pip 安装
pip install python-dotenv

说明:

  • python-dotenv 是第三方库,需要单独安装
  • 使用 pip install 命令安装

3.2 验证安装 #

安装后可以验证是否安装成功:

# 导入 dotenv 模块
import dotenv

# 打印版本号
# __version__ 是模块的版本属性
print(f"python-dotenv 版本:{dotenv.__version__}")

# 主程序入口
if __name__ == "__main__":
    print("python-dotenv 安装成功!")

说明:

  • dotenv.__version__ 显示安装的版本
  • 如果导入成功,说明安装正确

4. .env 文件格式 #

4.1 基本语法 #

.env 文件使用简单的键值对格式:

# .env 文件示例
# 这是注释,以 # 开头

# 基本格式:KEY=value
API_KEY=sk-1234567890abcdef

# 带空格的值需要用引号
APP_NAME="My Application"

# 数字值(仍然是字符串)
PORT=8000

# 布尔值(仍然是字符串)
DEBUG=True

说明:

  • 每行一个环境变量
  • 格式:KEY=value(等号两边可以有空格)
  • 以 # 开头的是注释
  • 值中的空格需要用引号包裹

4.2 实际项目示例 #

# .env 文件示例
# 数据库配置
DATABASE_URL=postgresql://user:password@localhost:5432/mydb

# API 密钥
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
STRIPE_SECRET_KEY=sk_test_xxxxxxxxxxxxxxxxxxxxxxxx

# 应用配置
DEBUG=True
SECRET_KEY=your-secret-key-here
ALLOWED_HOSTS=localhost,127.0.0.1,example.com

# 服务配置
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USE_TLS=True

说明:

  • 不同类型的配置可以分组(用注释分隔)
  • 敏感信息(如密码、密钥)存储在 .env 文件中
  • 不要将 .env 文件提交到版本控制系统

5. 基本使用 #

5.1 最简单的用法 #

# 导入必要的模块
import os
from dotenv import load_dotenv

# 加载 .env 文件
# load_dotenv() 会自动查找当前目录下的 .env 文件
load_dotenv()

# 获取环境变量
# os.getenv() 从 os.environ 中获取环境变量的值
api_key = os.getenv('API_KEY')
database_url = os.getenv('DATABASE_URL')

# 打印环境变量
print(f"API Key: {api_key}")
print(f"Database URL: {database_url}")

# 主程序入口
if __name__ == "__main__":
    print("环境变量加载成功!")

说明:

  • load_dotenv() 从 .env 文件加载环境变量到 os.environ
  • os.getenv() 获取环境变量的值
  • 如果环境变量不存在,os.getenv() 返回 None

5.2 指定 .env 文件路径 #

可以指定 .env 文件的具体路径:

# 导入必要的模块
from dotenv import load_dotenv
from pathlib import Path

# 方法 1:指定相对路径
# 加载当前目录下的 .env.local 文件
load_dotenv('.env.local')

# 方法 2:指定绝对路径
# 加载指定路径的 .env 文件
load_dotenv('/absolute/path/to/.env')

# 方法 3:使用 Path 对象
# Path 对象可以更方便地处理路径
env_path = Path('.') / '.env'
load_dotenv(dotenv_path=env_path)

# 主程序入口
if __name__ == "__main__":
    print("从指定路径加载 .env 文件")

说明:

  • 可以指定 .env 文件的具体路径
  • 使用 Path 对象可以更方便地处理路径
  • 如果文件不存在,load_dotenv() 不会报错(静默失败)

5.3 配置选项 #

load_dotenv() 函数支持多个配置选项:

# 导入必要的模块
from dotenv import load_dotenv

# 加载 .env 文件,使用配置选项
load_dotenv(
    dotenv_path='.env',          # .env 文件路径(默认是 .env)
    verbose=True,                # 显示加载信息(默认是 False)
    override=False,             # 是否覆盖已存在的环境变量(默认是 False)
    interpolate=True,           # 是否进行变量插值(默认是 True)
    encoding='utf-8'            # 文件编码(默认是 utf-8)
)

# 主程序入口
if __name__ == "__main__":
    print("使用配置选项加载 .env 文件")

说明:

  • dotenv_path:指定 .env 文件路径
  • verbose:是否显示加载信息
  • override:是否覆盖已存在的环境变量
  • interpolate:是否进行变量插值(如 ${VAR})
  • encoding:文件编码

6. 常用功能 #

6.1 获取环境变量(带默认值) #

# 导入必要的模块
import os
from dotenv import load_dotenv

# 加载 .env 文件
load_dotenv()

# 获取环境变量(带默认值)
# os.getenv() 的第二个参数是默认值
# 如果环境变量不存在,返回默认值
port = os.getenv('PORT', '8000')
debug = os.getenv('DEBUG', 'False')
api_key = os.getenv('API_KEY', 'default-key')

# 打印结果
print(f"Port: {port}")
print(f"Debug: {debug}")
print(f"API Key: {api_key}")

# 主程序入口
if __name__ == "__main__":
    print("获取环境变量(带默认值)")

说明:

  • os.getenv(key, default) 可以指定默认值
  • 如果环境变量不存在,返回默认值
  • 这样可以避免 None 值导致的错误

6.2 类型转换 #

环境变量都是字符串类型,需要时可以进行类型转换:

# 导入必要的模块
import os
from dotenv import load_dotenv

# 加载 .env 文件
load_dotenv()

# 字符串类型(默认)
# 环境变量都是字符串类型
debug_str = os.getenv('DEBUG', 'False')
print(f"Debug (字符串): {debug_str}, 类型: {type(debug_str).__name__}")

# 转换为布尔值
# 将字符串转换为布尔值
debug_bool = os.getenv('DEBUG', 'False').lower() == 'true'
print(f"Debug (布尔值): {debug_bool}, 类型: {type(debug_bool).__name__}")

# 转换为整数
# 使用 int() 将字符串转换为整数
port = int(os.getenv('PORT', '8000'))
print(f"Port: {port}, 类型: {type(port).__name__}")

# 转换为列表
# 使用 split() 将逗号分隔的字符串转换为列表
hosts_str = os.getenv('ALLOWED_HOSTS', 'localhost,127.0.0.1')
hosts = [item.strip() for item in hosts_str.split(',') if item.strip()]
print(f"Allowed Hosts: {hosts}, 类型: {type(hosts).__name__}")

# 主程序入口
if __name__ == "__main__":
    print("类型转换示例")

说明:

  • 环境变量都是字符串类型
  • 需要时可以使用 int()、bool() 等函数转换
  • 列表可以使用 split() 方法分割

6.3 辅助函数 #

可以创建辅助函数来简化类型转换:

# 导入必要的模块
import os
from dotenv import load_dotenv

# 加载 .env 文件
load_dotenv()

# 定义辅助函数:获取布尔值环境变量
def get_env_bool(key, default=False):
    """获取布尔值环境变量"""
    # 获取环境变量的值(字符串)
    value = os.getenv(key, str(default))
    # 转换为小写并检查是否为 'true'、'1' 或 'yes'
    return value.lower() in ('true', '1', 'yes')

# 定义辅助函数:获取列表环境变量
def get_env_list(key, default=''):
    """获取列表环境变量"""
    # 获取环境变量的值
    value = os.getenv(key, default)
    # 按逗号分割,去除空白,过滤空字符串
    return [item.strip() for item in value.split(',') if item.strip()]

# 定义辅助函数:获取整数环境变量
def get_env_int(key, default=0):
    """获取整数环境变量"""
    # 获取环境变量的值
    value = os.getenv(key, str(default))
    # 转换为整数
    try:
        return int(value)
    except ValueError:
        # 如果转换失败,返回默认值
        return default

# 使用辅助函数
debug = get_env_bool('DEBUG', False)
port = get_env_int('PORT', 8000)
hosts = get_env_list('ALLOWED_HOSTS', 'localhost')

# 打印结果
print(f"Debug: {debug}, 类型: {type(debug).__name__}")
print(f"Port: {port}, 类型: {type(port).__name__}")
print(f"Hosts: {hosts}, 类型: {type(hosts).__name__}")

# 主程序入口
if __name__ == "__main__":
    print("使用辅助函数获取环境变量")

说明:

  • 辅助函数可以简化类型转换
  • get_env_bool() 将字符串转换为布尔值
  • get_env_list() 将逗号分隔的字符串转换为列表
  • get_env_int() 将字符串转换为整数

6.4 直接获取所有变量(不修改 os.environ) #

dotenv_values() 可以直接获取 .env 文件中的所有变量,而不修改 os.environ:

# 导入必要的模块
from dotenv import dotenv_values

# 直接获取 .env 文件中的所有变量
# dotenv_values() 返回一个字典,包含所有环境变量
# 不会修改 os.environ
config = dotenv_values('.env')

# 打印所有配置
print("所有环境变量:")
for key, value in config.items():
    print(f"  {key} = {value}")

# 访问特定变量
api_key = config.get('API_KEY')
database_url = config.get('DATABASE_URL')

print(f"\nAPI Key: {api_key}")
print(f"Database URL: {database_url}")

# 主程序入口
if __name__ == "__main__":
    print("直接获取所有环境变量")

说明:

  • dotenv_values() 返回字典,包含所有环境变量
  • 不会修改 os.environ
  • 适合只需要读取配置,不需要修改系统环境变量的场景

7. 实际应用示例 #

7.1 简单的配置管理 #

创建一个简单的配置管理类:

# 导入必要的模块
import os
from dotenv import load_dotenv

# 加载 .env 文件
load_dotenv()

# 定义配置类
class Config:
    """应用配置类"""

    # 从环境变量获取配置
    # SECRET_KEY 是应用密钥(用于加密等)
    SECRET_KEY = os.getenv('SECRET_KEY', 'default-secret-key')

    # DEBUG 模式(开发时启用)
    DEBUG = os.getenv('DEBUG', 'False').lower() == 'true'

    # 数据库 URL
    DATABASE_URL = os.getenv('DATABASE_URL', 'sqlite:///db.sqlite3')

    # API 密钥
    API_KEY = os.getenv('API_KEY')

    # 端口号(转换为整数)
    PORT = int(os.getenv('PORT', '8000'))

    # 允许的主机(转换为列表)
    ALLOWED_HOSTS = os.getenv('ALLOWED_HOSTS', 'localhost').split(',')

# 创建配置实例
config = Config()

# 打印配置信息
print("应用配置:")
print(f"  Secret Key: {config.SECRET_KEY[:20]}...")
print(f"  Debug: {config.DEBUG}")
print(f"  Database URL: {config.DATABASE_URL}")
print(f"  API Key: {config.API_KEY}")
print(f"  Port: {config.PORT}")
print(f"  Allowed Hosts: {config.ALLOWED_HOSTS}")

# 主程序入口
if __name__ == "__main__":
    print("配置管理示例")

说明:

  • 使用类来组织配置,更清晰
  • 所有配置都从环境变量读取
  • 可以设置默认值,避免配置缺失

7.2 配置验证 #

在应用启动时验证必要的配置是否存在:

# 导入必要的模块
import os
from dotenv import load_dotenv

# 加载 .env 文件
load_dotenv()

# 定义配置验证器
class ConfigValidator:
    """配置验证器:检查必要的配置是否存在"""

    # 定义必要的配置项
    REQUIRED_KEYS = [
        'SECRET_KEY',
        'DATABASE_URL',
        'API_KEY'
    ]

    @classmethod
    def validate(cls):
        """验证配置"""
        # 存储缺失的配置项
        missing = []

        # 检查每个必要的配置项
        for key in cls.REQUIRED_KEYS:
            # 如果配置项不存在或为空,添加到缺失列表
            if not os.getenv(key):
                missing.append(key)

        # 如果有缺失的配置项,抛出异常
        if missing:
            raise ValueError(f"缺少必要的环境变量: {', '.join(missing)}")

        # 所有配置都存在
        print("✓ 所有必要配置已设置")

# 主程序入口
if __name__ == "__main__":
    # 在应用启动时验证配置
    try:
        ConfigValidator.validate()
        print("应用可以正常启动")
    except ValueError as e:
        print(f"配置错误:{e}")
        print("请检查 .env 文件,确保所有必要的配置都已设置")

说明:

  • 配置验证器检查必要的配置是否存在
  • 如果缺少配置,抛出异常,避免应用启动后出错
  • 在应用启动时调用验证器

8. 最佳实践 #

8.1 项目结构 #

推荐的项目结构:

my_project/
├── .env.example      # 示例配置(提交到版本控制)
├── .env              # 实际配置(不提交到版本控制)
├── .gitignore        # 包含 .env
├── config.py         # 配置加载代码
└── main.py           # 主程序

说明:

  • .env.example 是示例文件,包含配置项但不包含真实值
  • .env 是实际配置文件,包含真实值,不提交到版本控制
  • .gitignore 中应该包含 .env

8.2 创建 .env.example #

创建 .env.example 文件作为模板:

# .env.example
# 复制此文件为 .env 并填写实际值

# 数据库配置
DATABASE_URL=postgresql://user:password@localhost:5432/dbname

# 安全密钥
SECRET_KEY=your-secret-key-here

# API 密钥
API_KEY=your-api-key-here

# 应用设置
DEBUG=True
PORT=8000
ALLOWED_HOSTS=localhost,127.0.0.1

说明:

  • .env.example 是模板文件,不包含敏感信息
  • 新开发者可以复制 .env.example 为 .env 并填写实际值
  • .env.example 可以提交到版本控制

8.3 .gitignore 配置 #

在 .gitignore 中添加 .env 文件:

# .gitignore
# 忽略 .env 文件(包含敏感信息)
.env

# 忽略所有 .env 相关文件
.env.local
.env.*.local

说明:

  • .env 文件包含敏感信息,不应该提交到版本控制
  • 在 .gitignore 中添加 .env,确保不会被提交

9. 常见问题 #

9.1 .env 文件未找到 #

如果 .env 文件不在当前目录,需要指定路径:

# 导入必要的模块
from dotenv import load_dotenv
from pathlib import Path

# 确保路径正确
# Path(__file__).parent 获取当前文件所在目录
env_path = Path(__file__).parent / '.env'

# 检查文件是否存在
if env_path.exists():
    # 文件存在,加载环境变量
    load_dotenv(env_path)
    print(f"✓ 已加载 {env_path}")
else:
    # 文件不存在,显示警告
    print(f"警告: 未找到 {env_path}")

# 主程序入口
if __name__ == "__main__":
    print("检查 .env 文件是否存在")

说明:

  • 使用 Path(__file__).parent 获取当前文件所在目录
  • 检查文件是否存在,避免静默失败
  • 如果文件不存在,显示警告信息

9.2 环境变量未加载 #

如果环境变量未加载,可以检查:

# 导入必要的模块
import os
from dotenv import load_dotenv

# 使用 override=True 强制覆盖
# override=True 会覆盖已存在的环境变量
load_dotenv(override=True)

# 检查是否加载成功
# 尝试获取一个环境变量
my_key = os.environ.get('MY_KEY')

if my_key:
    print(f"✓ 环境变量已加载: MY_KEY = {my_key}")
else:
    print("✗ 环境变量未加载,请检查 .env 文件")

# 打印所有环境变量(仅用于调试)
# print("所有环境变量:")
# for key, value in os.environ.items():
#     if key.startswith('MY_'):
#         print(f"  {key} = {value}")

# 主程序入口
if __name__ == "__main__":
    print("检查环境变量是否加载")

说明:

  • 使用 override=True 强制覆盖已存在的环境变量
  • 检查环境变量是否存在
  • 可以打印所有环境变量用于调试

9.3 环境变量值为 None #

如果环境变量不存在,os.getenv() 返回 None,需要处理:

# 导入必要的模块
import os
from dotenv import load_dotenv

# 加载 .env 文件
load_dotenv()

# 方法 1:使用默认值
# 如果环境变量不存在,使用默认值
api_key = os.getenv('API_KEY', 'default-key')
print(f"API Key: {api_key}")

# 方法 2:检查是否为 None
# 如果环境变量不存在,进行特殊处理
database_url = os.getenv('DATABASE_URL')
if database_url is None:
    print("警告: DATABASE_URL 未设置,使用默认值")
    database_url = 'sqlite:///db.sqlite3'
print(f"Database URL: {database_url}")

# 方法 3:使用 os.environ.get()(与方法 1 相同)
# os.environ.get() 也可以指定默认值
secret_key = os.environ.get('SECRET_KEY', 'default-secret-key')
print(f"Secret Key: {secret_key}")

# 主程序入口
if __name__ == "__main__":
    print("处理环境变量为 None 的情况")

说明:

  • 使用默认值避免 None 值
  • 检查是否为 None 并进行特殊处理
  • os.environ.get() 也可以指定默认值

10. 总结 #

10.1 核心概念回顾 #

  • python-dotenv:从 .env 文件加载环境变量的工具
  • .env 文件:存储环境变量的文本文件
  • load_dotenv():加载 .env 文件中的环境变量
  • os.getenv():获取环境变量的值

10.2 基本使用流程 #

  1. 安装:pip install python-dotenv
  2. 创建 .env 文件:在项目根目录创建 .env 文件
  3. 加载环境变量:load_dotenv()
  4. 使用环境变量:os.getenv('KEY')

10.3 使用 python-dotenv 的好处 #

  1. 安全:敏感信息不写在代码中
  2. 灵活:不同环境可以使用不同的配置
  3. 简单:一行代码就能加载所有配置
  4. 版本控制友好:.env 文件不提交,保护敏感信息
← 上一节 python-docx 下一节 python-pptx →

访问验证

请输入访问令牌

Token不正确,请重新输入