跳至主要内容

Python 环境变量:您需要了解的内容

学习如何使用 os 和 python-dotenv 库管理 Python 环境变量的方方面面。
· 9分钟 阅读

使用 AI 探索

环境变量是一种功能强大的机制,可灵活且安全地存储开发项目的配置信息。它们以键值对的形式存储数据,编程语言(如 Python)可以访问,同时将这些信息对好奇者隐藏。在本教程中,您将学习在 Python 中创建和管理环境变量必须掌握的概念与技巧。

什么是环境变量?

环境变量是在您的操作系统中某个安全位置存储的名称-值对。通常,它们看起来像这样:

API_KEY=1akn4nka-aqwej3

在 Python 中,您可以使用此类变量来存储与开发项目相关的敏感信息。敏感信息可以包括:

  • 用于访问他人应用的 API 密钥
  • 通过脚本登录应用所需的用户名和密码
  • 数据库凭据
  • 任何一旦意外泄露可能导致安全问题的内容。

例如,如果您在 Python 脚本中明文使用了 AWS 凭据,并不小心将该脚本提交到 GitHub,恶意人士可能会发现它并大幅增加您的 AWS 账单(这种情况确实发生过)。

环境变量的另一个好处是可配置性。您可以通过修改环境变量轻松调整设置(如数据库 URL、文件路径),而无需更改代码。如果您在项目的多个部分使用相同设置,这一特性尤其有用。

那么,让我们来学习如何在 Python 中使用它们。

如何使用 Python 的 os 模块获取环境变量

要检索系统中已存在的环境变量,您可以使用 os 模块。它提供了 .getenv 函数来获取变量:

import os
os.getenv("USER")
'bexgboost'

上面我获取的是系统用户名,这是所有系统都内置的变量。还有许多类似的变量,比如主目录路径:

os.getenv("HOME")
'/home/bexgboost'

或者您的 Conda 可执行文件路径:

os.getenv("CONDA_EXE")
'/home/bexgboost/anaconda3/bin/conda'

因此,当您运行 conda 命令时,终端就是通过它来知道应运行哪个程序。

但如果您尝试获取一个不存在的变量会怎样:

os.getenv("MYDATABASE")

.getenv() 函数不会返回任何内容,但我们可以改变这种行为。您可以使用它的 default 参数,在变量不存在时返回自定义值:

os.getenv("COMPUTER_PASSWORD", default="Nope!")
'Nope!'

.getenv() 函数是检索现有变量的最佳方法。

然而,在其他资料中,您可能会看到不同的方法,比如 .environ 属性,它会返回一个包含所有环境变量的字典:

current_directory = os.environ.get("PWD", None)
current_directory
'/home/bexgboost/articles/2024/4_april'

由于它是一个字典,您可以使用中括号(不推荐)或 .get() 函数来获取值。

os 还可以访问也许是最重要的系统变量 PATH。PATH 保存系统上已安装的所有可执行文件的绝对路径,因此它通常很长:

os.getenv("PATH")[:46]
'/home/bexgboost/.local/bin:/home/bexgboost/bin'

PATH 中的每个路径都用冒号分隔。让我们数一下我系统上 PATH 的长度:

def count_path_items():
   items = os.getenv("PATH").split(":")

   return len(items)

count_path_items()
79

79!不错。

使用 python-dotenv 库高效管理 Python 中的环境变量

设置自定义环境变量

现在我们已经知道如何提取现有变量了,接下来看看如何设置自定义变量。第一种方法是使用 os.environ 字典:

# Create a new environment variable
os.environ["NEW_VARIABLE"] = "42"  # Always expects a string value

os.getenv("NEW_VARIABLE")
'42'

不过,这种方法并不太实用,因为所有新变量在当前会话结束后都会丢失。

幸运的是,还有一种更持久的方式是使用 .env 文件(读作 dot-env)来存储环境变量。这些文件的语法相同,意味着它们可在任何操作系统上使用。下面是一个示例 .env 文件的样子:

CUSTOM_API_LINK=https://myapi.com/v1/api
SNOWFLAKE_USERNAME=bexgboost
MYSQL_DATABASE_PASSWORD=as3ndf03

目前,它只定义了三个变量。要读取该文件并提取其内容,我们将使用一个名为 python-dotenv 的库:

$ pip install python-dotenv

然后,在 Python 脚本或 Jupyter Notebook 中导入它的 load_dotenv 函数并调用:

from dotenv import load_dotenv

load_dotenv()
True

如果它在当前目录找不到 .env 文件,就会向上搜索各级父目录,若找到则返回 True。

我把上面的 .env 文件存放在主目录 ~/.env;这就是 load_dotenv 能找到它的原因。

要创建您自己的文件,您可以在终端使用 touch 命令,或使用 VSCode 等文本编辑器:

$ touch ~/.env

.env 文件的语法相当灵活。例如,您可以设置多行值的变量(必须加引号):

LONG_ENV="This is an environment
variable with a long message"

使用转义字符:

LONG_ENV="This value uses an \"escape character"

您还可以在文件中添加注释以供将来参考:

# You can also add comments anywhere with a hashtag
CUSTOM_API_LINK=https://myapi.com/v1/api
SNOWFLAKE_USERNAME=bexgboost
MYSQL_DATABASE_PASSWORD=as3ndf03

还可以使用 ${VAR_NAME} 语法在一个变量的值中引用另一个变量:

FIRST_NAME=John
LAST_NAME=Doe
FULL_NAME="I am ${FIRST_NAME} ${LAST_NAME}"

使用 python-dotenv 获取自定义环境变量

获取自定义变量与之前相同——直接使用 os 模块即可:

import os

os.getenv("CUSTOM_API_LINK")
'https://myapi.com/v1/api'
os.getenv("SNOWFLAKE_USERNAME")
'bexgboost'

请确保先调用 load_dotenv。

如果您的 .env 文件位于 load_dotenv 无法到达的位置,可以像下面这样传入其绝对路径:

load_dotenv("/home/bexgboost/somewhere/unreachable/.env")
True

在 Jupyter 中使用 .env 文件

安装 Python-dotenv 后,如果您使用的是 Jupyter,就无需在 Python 中显式导入。该库带有一个 Jupyter magic 方法,会自动加载:

# Run this anywhere in the notebook to load EVs from .env
%load_ext dotenv
%dotenv

然后,您可以再次使用 os 模块:

import os

os.getenv("SNOWFLAKE_USERNAME")
'bexgboost'

在 Python 中使用环境变量的最佳实践

本节我们将列出一些最佳实践,确保环境变量既安全又易用。

1. 始终将 .env 文件添加到 .gitignore,以免不小心将其提交到 GitHub。

# Create .gitignore if it doesn't exist
$ touch .gitignore
$ echo ".env" >> .gitignore

2. 定义变量时使用具描述性的、全部大写的名称。

# Good
DEBUG=True
LOGGING_VERBOSITY=3

# Bad
debug=True
LV=3

3. 创建一个统一的 .env 文件来存放您在每个项目中都需要的系统级变量。

$ touch ~/.env

4. 控制 .env 文件的作用域。为开发流程的不同环节分别创建文件,如下所示:

$ touch development/.env.development
$ touch testing/.env.testing
$ touch production/.env.production

load_dotenv 函数会识别它们。

如果您创建了多个不同名称的 .env 文件,请修改 .gitignore 文件,使它们都被排除在 git 索引之外:

# Pay attention to the asterisk *
$ echo ".env*" >> .gitignore

结语

在本文中,我们学习了在 Python 中高效管理环境变量所需的关键概念与技巧。我们了解了如何使用 Python 的 OS 模块检索现有变量,以及如何通过 python-dotenv 库创建自定义值。我们还学习了如何编写符合最佳实践的 .env 文件。

如果您想进一步学习 Python 软件工程,请查看我们的课程 Software Engineering Principles in Python。

您也可以查看我们的 Python Programming Skill Track,通过实操练习与项目,从入门成长为高级 Python 开发者。

Bexruz (Bex) Tuychiev

作者

Bexruz (Bex) Tuychiev

我是一名数据科学内容创作者,拥有超过 2 年的经验,并在 Medium 上拥有较大的读者群。我喜欢用略带讽刺的笔调撰写有关 AI 和机器学习的深度文章——毕竟总得想点办法让这些内容不那么枯燥。我已发表 130 多篇文章,并制作了一门 DataCamp 课程,另有一门正在筹备中。我的内容已被超过 500 万人次阅读,其中有 2 万人在 Medium 和 LinkedIn 上成为关注者。 

主题