zoukankan      html  css  js  c++  java
  • Python项目读取配置的几种方式

    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,方便开发和运维。

  • 相关阅读:
    HTML总结
    Java 基础知识总结 (三、运算符)
    关于JS 事件冒泡和onclick,click,on()事件触发顺序
    Java 基础知识总结 (四、String)
    Java 基础知识总结 (二、基本数据类型)
    websocket实例(显示文件导入处理进度)
    Java 基础知识总结 (一、标识符)
    Java Calendar 注意事项
    Ajax调用SpringMVC ModelAndView 无返回情况
    关于Ajax load页面中js部分$(function(){})的执行顺序
  • 原文地址:https://www.cnblogs.com/zhangyafei/p/10265072.html
Copyright © 2011-2022 走看看