1. 将配置写在Python文件中

  • 配置文件(config.py 或 settings.py) 通常放置在程序源代码的目录,方便引用

 配置文件

# settings.py
class Config(object):
DEBUG = False
TESTING = False
DATABASE_URI = 'sqlite://:memory:' class ProductionConfig(Config):
DATABASE_URI = 'mysql://user@localhost/foo' class DevelopmentConfig(Config):
DEBUG = True class TestingConfig(Config):
TESTING = True 

读取

import importlib

path = 'settings.Foo'

p,c = path.rsplit('.',maxsplit=1)
m = importlib.import_module(p)
# m = __import__(p)
cls = getattr(m,c) for key in dir(cls):
if key.isupper():
print(key,getattr(cls,key))

 这种方法非常简单,直接把配置的内容写到了代码中,在应用中直接进行引用。另外也可以把这个py配置文件放到其他python应用中,修改具体的配置内容即可。但是,它存在严重的安全问题,我们都知道不应该把配置写到代码中,如果有人把我们的源代码上传到了github中,那么数据库的配置就相当于向全世界公开了。当然,当配置文件不包含敏感信息时,也可以采用这种简单的方法。

2. 利用外部配置文件

更常见的配置管理方法就是利用外部的配置文件,让配置文件仅仅包含配置信息,和代码独立开来,不直接引用也就不需要写成python代码。通常使用json、yaml或者ini的文件格式来存储配置。

利用configparse

写入文件
import configparser config = configparser.ConfigParser() config["DEFAULT"] = {'ServerAliveInterval': '45',
'Compression': 'yes',
'CompressionLevel': '9',
'ForwardX11':'yes'
} config['bitbucket.org'] = {'User':'hg'} config['topsecret.server.com'] = {'Host Port':'50022','ForwardX11':'no'} with open('example.ini', 'w') as file: config.write(file)

配置文件

# example.ini
[DEFAULT]
serveraliveinterval = 45
compression = yes
compressionlevel = 9
forwardx11 = yes [bitbucket.org]
user = hg [topsecret.server.com]
host port = 50022
forwardx11 = no

  除此之外,我们还可以用json文件来存储

# config.json
{
"DATABASE": {
"host": "localhost",
"dbname": "test",
"user": "user",
"password": "password",
"port": 3306
}
}

结合环境变量和python库configparser读取外部文件,首先在开发通常不会接触到生产环境,因此生产环境的配置文件由运维来写,运维将应用所需要的配置写好后,放到生产服务器的指定位置,代码从指定位置读取配置。为了方便程序的统一调试,可以提前约定好一个系统环境变量(CONFIG_PATH)来指定配置文件的存放路径。

export CONFIG_PATH = /home/test/configs/config.ini

读取的代码如下:

import os
import configparser try:
CONFIG_PATH = os.environ['CONFIG_PATH']
except Exception:
raise ValueError config = configparser.ConfigParser()
config.read(CONFIG_PATH) host = config["DATABASE"]["HOST"]

3. 直接使用系统环境变量读取配置

此方法不使用文件来存储配置信息,将所有的配置信息存储到环境变量中,在实践中也比较常见,运维通过ansible部署脚本,在程序运行前将需要配置信息导入到环境变量中。

import os

secret_key = os.environ.get('SECRET_KEY', None)

if not secret_key:
raise ValueError('You must have "SECRET_KEY" variable') app.config['SECRET_KEY'] = secert_key

不利用文件存储,在一定程度上加强了对密码等配置信息的保护,但也增加了运维的工作量,尤其当需要修改配置的时候。

4. Dynaconf:Pyhton项目的动态配置

上面介绍了三种常见的项目配置方法,最有介绍一个好用的python动态项目配置库:Dynaconf。dyanconf是OSM(Object Settings Mapper), 能够从不同的配置数据存储方式中读取配置,例如python配置文件、系统环境变量、redis、ini文件、json文件等等。

安装:pip install dynaconf

使用方式:

from dynaconf import settings
print(settings.SOME_VARIABLE)
or
print(settings.get('SOME_VARIABLE'))

如果不希望配置跟随项目,可以通过系统环境变量来指定配置文件的位置

# using module name
export DYNACONF_SETTINGS=myproject.production_settings
# or using location path
export DYNACONF_SETTINGS=/etc/myprogram/settings.py 

4.1 dyanconf读取系统环境变量中的配置

当我们部署的程序需要读取一个MYSQL_HOST的配置用于测试,不需要去重写配置文件,仅需要再系统环境变量中加入:

export DYNACONF_MYSQL_HOST=myserver.com

然后,程序便可以获取到该配置:

>>> from dynaconf import settings
>>> print(settings.MYSQL_HOST)
myserver.com

如果需要指定配置值的数值类型,则通过以下方式增加对应的系统环境变量:

export DYNACONF_NUMBER='@int 123'
export DYNACONF_FLOAT='@float 12.2'
export DYNACONF_FLAG='@bool yes'
export DYNACONF_FLAG2='@bool disabled'
export DYNACONF_LIST='@json [1, 2, 3, 4]'
export DYNACONF_DICT='@json {"name": "Bruno"}'

读取到的配置如下所示:

from dynaconf import settings

type(settings.NUMBER)
int type(settings.FLOAT)
float type(settings.FLAG)
bool print(settings.FLAG2 == False)
True print(settings.LIST[1])
2 print(settings.DICT['name'])
Bruno

4.2 通过redis存储配置

我们也可以讲配置文件存储到redis中,达到在对不同的机器共享环境变量的效果,仅需要在settings.py文件中增加一下代码:

# connection
REDIS_FOR_DYNACONF = {
'host': 'localhost',
'port': 6379,
'db': 0
} # and loader
LOADERS_FOR_DYNACONF = [
'dynaconf.loaders.env_loader',
'dynaconf.loaders.redis_loader' # 增加了redis的加载
]

现在可以讲配置存储到redis中,hash默认为DYNACONF_DYNACONF。dyanconf还提供了方法去将配置写入到redis:

from dynaconf.utils import redis_writer
from dynaconf import settings redis_writer.write(settings,name='test',mysql_host='localhost', MYSQL_PORT=3306)

查看Redis,存储的结果如下:

DYNACONF_DYNACONF:
NAME='test'
MYSQL_HOST='localhost'
PORT='@int 3306'

至此,python项目常见的配置方法总结完毕,不过在一些微服务架构中,会专门开发配置中心,程序直接从线上读取配置,配置的管理也会开发一套GUI,方便开发和运维。

Python项目读取配置的几种方式的更多相关文章

  1. Spring Boot读取配置的几种方式

    读取application文件 在application.yml或者properties文件中添加: info.address=USAinfo.company=Springinfo.degree=hi ...

  2. Spring Boot读取配置的 5 种方式

    读取application文件 在application.yml或者properties文件中添加: info.address=USA info.company=Spring info.degree= ...

  3. springboot 读取 yml 配置的几种方式

    前言:在springboot 项目中一般默认的配置文件是application.properties,但是实际项目中我们一般会使用application.yml 文件,下面就介绍一下在springbo ...

  4. python项目实现配置统一管理的方法

    一个比较大的项目总是会涉及到很多的参数,最好的方法就是在一个地方统一管理这些参数.最近看了不少的python项目,总结了两种很有意思的配置管理方法. 第一种 基于easydict实现的配置管理 首先需 ...

  5. Python实现微信支付(三种方式)

    Python实现微信支付(三种方式) 关注公众号"轻松学编程"了解更多. 如果需要python SDk源码,可以加我微信[1257309054] 在文末有二维码. 一.准备环境 1 ...

  6. Spring Boot 入门系列(二十五)读取配置文件的几种方式详解!

    在项目开发中经常会用到配置文件,之前介绍过Spring Boot 资源文件属性配置的方法,但是很多朋友反馈说介绍的不够详细全面.所以, 今天完整的分享Spring Boot读取配置文件的几种方式! S ...

  7. Spring事务配置的五种方式和spring里面事务的传播属性和事务隔离级别

    转: http://blog.csdn.net/it_man/article/details/5074371 Spring事务配置的五种方式 前段时间对Spring的事务配置做了比较深入的研究,在此之 ...

  8. spring配置datasource三种方式

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp34 spring配置datasource三种方式 1.使用org.spri ...

  9. 【转】Spring学习---Bean配置的三种方式(XML、注解、Java类)介绍与对比

    [原文]https://www.toutiao.com/i6594205115605844493/ Spring学习Bean配置的三种方式(XML.注解.Java类)介绍与对比 本文将详细介绍Spri ...

随机推荐

  1. 微信小程序支付证书及SSL证书使用

    小程序使用微信支付包括:电脑管理控制台导入证书->修改代码为搜索证书->授权IIS使用证书->设置TSL加密级别为1.2 描述: 1.通常调用微信生成订单接口的时候,使用的证书都是直 ...

  2. c/c++ 继承与多态 友元与继承

    问题1:类B是类A的友元类,类C是类B的友元类,那么类C是类A的友元类吗?函数fun是类B的友元函数,那么fun是类A的友元函数吗? 都不是,友元关系不能传递. 问题2:类B是类A的友元类,类C是类B ...

  3. Swift代理的使用

    Swift代理的使用 协议规定了用来实现某一特定功能所必需的方法和属性. 任意能够满足协议要求的类型被称为遵循(conform)这个协议. 类,结构体或枚举类型都可以遵循协议,并提供具体实现来完成协议 ...

  4. Vue学习之路1-集成环境安装

    1.前言 Vue 是一款友好的.多用途且高性能的javascript框架,与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用,它能够帮你创建可维护性和可测试性更强的代码库,Vue是渐进式的j ...

  5. requests模块

    import requests url='https://www.cnblogs.com/Eva-J/p/7277026.html' get = requests.get(url) print(get ...

  6. C#基础知识之字符串比较方法:“==”操作符;RefernceEquals;String.Equals方法;String.Compare方法;String.CompareOrdinal方法。

    一.“==”操作符:String.Equals:ReferenceEquals 方法 1.在编程中实际上我们只需要这两种比较,c#中类型也就这两种 (1)值类型的比较:一般我们就是判断两个值类型实例各 ...

  7. Flink Pre-defined Timestamp Extractors / Watermark Emitters(预定义的时间戳提取/水位线发射器)

    https://ci.apache.org/projects/flink/flink-docs-release-1.6/dev/event_timestamp_extractors.html 根据官网 ...

  8. WiFi广告强推的基本技术原理和一些相关问题

    WiFi推原理(转) 本文地址:http://jb.tongxinmao.com/Article/Detail/id/412 WiFi广告强推的基本技术原理和一些相关问题 WiFi广告推送原理就是利用 ...

  9. zookeeper的分布式锁

    实现分布式锁目前有三种流行方案,分别为基于数据库.Redis.Zookeeper的方案,其中前两种方案网络上有很多资料可以参考,本文不做展开.我们来看下使用Zookeeper如何实现分布式锁. 什么是 ...

  10. 基于HTML5 的互联网+地铁行业

    前言 近几年,互联网与交通运输的融合,改变了交易模式,影响着运输组织和经营方式,改变了运输主体的市场结构.模糊了运营与非营运的界限,也更好的实现了交通资源的集约共享,同时使得更多依靠外力和企业推动交通 ...