在实际开发中,Flask项目常需要灵活的配置管理,通过.env
文件指定config.yaml
路径,优势在于:
- 支持环境变量替换,避免硬编码敏感信息
- 支持多环境配置(开发、测试、生产),便于切换
- 代码与配置分离,易于维护和部署
假设项目目录结构如下:
your-flask-app/
├── app.py
├── config/
│ ├── development.yaml
│ ├── production.yaml
│ └── testing.yaml
├── .env
├── .env.example
└── requirements.txt
构建一个 .env
文件来指定配置文件路径和其他环境变量:
FLASK_ENV=development
CONFIG_FILE=config/development.yaml
SECRET_KEY=your-secret-key
DATABASE_URL=sqlite:///app.db
同时,创建一个 config/development.yaml
文件作为示例配置:
app:
name: "My Flask App"
debug: true
secret_key: "${SECRET_KEY}"
database:
url: "${DATABASE_URL}"
实现Flask应用加载YAML配置文件的代码如下:
import os
import yaml
from flask import Flask
from dotenv import load_dotenv
import re
# 1. 加载.env文件
load_dotenv()
# 2. YAML配置加载类,支持环境变量替换
class Config:
def __init__(self, config_file=None):
self.config_file = config_file or os.getenv('CONFIG_FILE', 'config/development.yaml')
self.config = self.load_config()
def load_config(self):
if not os.path.exists(self.config_file):
raise FileNotFoundError(f"配置文件 {self.config_file} 不存在")
with open(self.config_file, 'r', encoding='utf-8') as f:
content = f.read()
content = self.substitute_env_vars(content)
return yaml.safe_load(content)
def substitute_env_vars(self, content):
def replace_env_var(match):
var_name = match.group(1)
return os.getenv(var_name, match.group(0))
return re.sub(r'\$\{([^}]+)\}', replace_env_var, content)
def get(self, key, default=None):
keys = key.split('.')
value = self.config
for k in keys:
if isinstance(value, dict) and k in value:
value = value[k]
else:
return default
return value
config = Config()
app = Flask(__name__)
app.config['SECRET_KEY'] = config.get('app.secret_key')
app.config['DEBUG'] = config.get('app.debug', False)
@app.route('/')
def home():
return {
'app_name': config.get('app.name'),
'database_url': config.get('database.url'),
}
if __name__ == '__main__':
app.run(debug=app.config['DEBUG'])
通过这种方式可以轻松地管理不同环境下的配置,同时保持代码的整洁和可维护性