是否想要更有效地管理你的配置?探索如何在Python中运用环境变量。
在自学Python的过程中,我通过构建项目来实践所学。其中一项任务是连接数据库并使用Python进行查询。这意味着我需要存储数据库的配置信息和敏感数据,比如用于身份验证的用户名和密码。
将此类敏感信息硬编码到Python脚本中显然不是一个好主意。我还学习了如何使用配置文件和环境变量,以及如何通过Python的内置模块来操作它们。
因此,每当需要在应用中使用密码和API密钥等敏感信息时,我都会将它们设置为环境变量,并根据需要提取。在本教程中,我将指导你了解环境变量及其在Python中的应用。
什么是环境变量?
环境变量是存在于应用程序外部的变量,用来存储配置信息、系统设置等。它们通常由操作系统或应用程序环境进行管理。环境变量的关键特点包括:
- 键值对:环境变量由名称(也称作键)和对应的值构成。
- 系统级范围:环境变量可以在系统级别设置,使得系统上运行的所有进程都可以访问。当然,你也可以在应用程序级别修改或定义它们,仅影响特定的应用程序。
- 动态和可变:环境变量可以在运行时被修改,提供极大的灵活性。
环境变量的益处
环境变量在管理Python应用中的配置信息和敏感数据方面有诸多好处:
- 关注点分离:通过将配置存储在代码之外,你可以将配置管理与应用程序逻辑分离。
- 安全性:你可以将API密钥和数据库凭证等敏感数据保存在环境变量中,避免直接暴露在源代码中,从而降低安全风险。
- 灵活性:使用环境变量,更新配置设置非常简单,你可以在代码库之外进行更改。环境变量允许你调整配置,而无需修改代码。这种灵活性在将应用部署到不同环境或更新凭证时尤为重要。
在本教程接下来的部分,我们将探讨如何在Python中设置、访问和管理环境变量,以及它们如何提升项目中的配置管理水平。
如何设置环境变量
你可以使用命令行设置环境变量。这种方式设置的环境变量仅限于当前会话,不会在会话结束后保留。
如果你使用的是Mac或Linux电脑,你可以在当前终端会话中通过以下方式设置环境变量:
export MY_VARIABLE=my_value
如果你是Windows用户,你可以通过以下方式临时设置环境变量:
set MY_VARIABLE=my_value
在Python中访问环境变量
Python提供了os模块用于执行与操作系统相关的功能。os.environ
是一个存储环境变量的字典。环境变量的名称及其值分别是字典的键和值。
因此,你可以通过使用环境变量的名称作为键来访问它们的值,就像访问字典元素一样。
以下是一些示例:
import os print(os.environ['HOME']) # Output: /home/balapriya
print(os.environ['USER']) # Output: balapriya
到目前为止一切顺利。但是,如果你尝试访问一个未设置的环境变量的值,会发生什么?
让我们尝试访问一个我们尚未设置的API_KEY:
print(os.environ['API_KEY'])
正如预期的,你会得到一个KeyError:
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<frozen os>", line 679, in __getitem__ KeyError: 'API_KEY'
处理KeyError
你可以通过以下方式处理KeyError:
import os try: api_key = os.environ['API_KEY'] print(f'API_KEY is set to: {api_key}') except KeyError: print('API_KEY is not set. Please configure it.')
此方法不会使程序在引发KeyError异常时立即停止运行,而是会提供一条描述性的错误消息:
# Output API_KEY is not set. Please configure it.
这样,当程序的其他部分未按预期工作时,我们就知道是缺少了必要的环境变量设置。
使用get()方法访问环境变量
你可以使用字典的get()
方法来获取环境变量的值。如果未找到变量,get()
方法会返回None
,而不是抛出KeyError。
访问一个我们尚未设置的NOT_SET变量不会返回KeyError,而是None
:
print(os.environ.get('NOT_SET')) # Output: None
我个人更倾向于在未设置环境变量时引发KeyError,而不是让它默默地传递或包含在get()
方法返回的None
中。
但是,当我们需要为特定环境变量提供默认值(如果未设置)时,get()
方法会非常有用。
以下是一个示例:
print(os.environ.get('HOME','/home/user')) # Output: /home/balapriya
如何使用环境变量管理配置
现在让我们来看几个在应用程序中使用环境变量的实际示例。
示例1:配置数据库连接参数
假设你想从Python连接到PostgreSQL数据库。为此,你可以安装并使用psycopg2连接器:
pip install psycopg2
在本例中,我们使用环境变量来配置数据库连接参数。如果环境变量未设置,我们会提供默认值:
import os import psycopg2 # 从环境变量中检索数据库配置 db_host = os.environ.get('DB_HOST', 'localhost') db_port = os.environ.get('DB_PORT', '5432') db_user = os.environ.get('DB_USER', 'myuser') db_password = os.environ.get('DB_PASSWORD', 'mypassword') # 建立数据库连接 try: connection = psycopg2.connect( host=db_host, port=db_port, user=db_user, password=db_password, database="mydb" ) print('Connected to the database!') except Exception as e: print(f'Error connecting to the database: {e}')
示例 2:管理 API 密钥
我们再来看一个涉及使用API密钥的例子。
除了ChatGPT界面之外,你还可以使用OpenAI API在你的应用中启用OpenAI LLM。
当你注册OpenAI帐户时,你(通常会看到)获得一些免费的限时API积分。通过导航到“设置”>“查看API密钥”来获取你的API密钥。
你可以使用Open AI Python SDK和LangChain等框架来构建应用。为此,你需要使用pip安装库(在虚拟环境中):
pip install openai pip install langchain
以下是将OPENAI_API_KEY设置为环境变量的方法:
import os os.environ["OPENAI_API_KEY"]='your-api-key'
你现在可以在脚本中访问Open AI LLM,如下所示:
from langchain.llms import OpenAI model=OpenAI(model_name="gpt-3.5-turbo")
如何在Python中修改环境变量
你可以通过访问os模块中的os.environ
字典来修改当前Python进程中的环境变量:
import os # 修改一个已存在的环境变量或创建一个新的 os.environ['MY_VARIABLE'] = 'new_value'
在Python中,你可以使用subprocess模块从现有的Python脚本创建子进程。当你需要在Python中执行系统程序时,这很有帮助。
在下面的示例中,我们通过利用os.environ
字典来修改PATH
环境变量。然后我们将echo $PATH
作为子进程运行:
import os import subprocess # 为子进程设置自定义环境变量 os.environ['PATH'] = '/custom/path' # 运行一个访问PATH环境变量的子进程 result = subprocess.run("echo $PATH", shell=True, stdout=subprocess.PIPE) output = result.stdout.decode() print(output) print(f'Subprocess output: {output}')
我们看到PATH
的值为/custom/path
:
# Output /custom/path
修改环境变量的作用域
需要注意的是,这些环境变量的更新是临时的,只对当前的Python进程有效。脚本结束后,所做的更改将会被丢弃:
- 当前Python进程:当你在Python脚本中使用
os.environ
修改环境变量时,所做的更改仅在当前Python进程中有效。它不会影响其他正在运行的进程或未来的Python会话。 - 子进程:当前Python进程中所做的环境变量更改将由脚本创建的子进程继承。例如,如果你从Python脚本(父进程)创建子进程,则子进程将有权访问修改后的环境变量(如示例所示)。
- 非系统范围:在Python脚本中设置的环境变量不会在该脚本执行之外保留。
如果你需要在系统级别对环境变量进行持久更改,通常需要使用操作系统特定的方法来实现。
如何使用python-dotenv加载.env文件
python-dotenv库是一个流行的Python包,它简化了将环境变量从.env
文件加载到Python项目中的过程。当你拥有多个具有不同配置的环境(例如,开发、生产)并且你希望将这些设置与源代码分离时,它特别有用。
安装python-dotenv
要使用python-dotenv,你需要先安装它。你可以使用Python包管理器pip在虚拟环境中安装它:
pip install python-dotenv
从.env文件加载环境变量
现在,你可以在项目的根目录中创建一个名为.env
的文件,并使用键值对填充它,就像常规的环境变量一样。让我们用占位符值创建一个如下的.env
文件:
API_KEY=your_api_key_here DB_PASSWORD=your_database_password_here
你现在可以使用python-dotenv从.env
文件加载环境变量,如下所示:
import os from dotenv import load_dotenv # 从.env文件加载环境变量 load_dotenv() # 访问环境变量 api_key = os.getenv("API_KEY") database_password = os.getenv("DB_PASSWORD") # 输出环境变量 print(f"API Key: {api_key}") print(f"Database Password: {database_password}")
请注意,我们使用os.getenv(VARIABLE_NAME)
来获取环境变量的值。这也是一种访问环境变量的有效(且不太常用的)方式。
以下是输出结果:
API Key: your-api-key-here Database Password: your-database-url-here
在这个例子中:
- 我们使用
load_dotenv()
将.env
文件中定义的环境变量加载到当前环境中。 - 然后我们使用
os.getenv()
来访问环境变量:API_KEY
和DB_PASSWORD
。
结论
就这样了!希望你已经了解了如何在Python应用中使用环境变量来管理配置和敏感信息。我们介绍了设置和访问环境变量的基础知识,以及它们在配置应用程序中的实际用途。
虽然环境变量有助于将配置与源代码分离,但你仍然应该在生产环境中将敏感变量存储为秘密。为了管理秘密,我建议你探索诸如HashiCorp Vault 或者 AWS Secret Manager之类的工具。