为什么.conf文件改为config.py文件?

时间:2016-12-08 05:28:00

标签: python configuration config configuration-files

我正在看几个python项目。几乎每个好的python项目通常都有一个 app.conf app.ini 文件用于配置管理。之后,他们使用.py模块之类的东西从 app.conf 文件中提取配置信息。最后,他们不得不使用[BREED] beagle=dog ragdoll=cat deilenaar=rabbit cockatoo=parrot 模块中的值。

让我们举个例子

app.conf

#!/usr/bin/env python
#-*- coding: utf-8 -*-

import configparser

config = configparser.ConfigParser()
config.read('app.conf')
print(config['BREED']['cockatoo']) # prints parrot

app.py

#!usr/bin/env python
# -*- coding: utf-8 -*-

config = {'BREED': {'beagle': 'dog',
                    'ragdoll': 'cat',
                    'deilenaar': 'rabbit',
                    'cockatoo': 'parrot'}}
print(config['BREED']['cockatoo']) # prints parrot

那么为什么不使用字典并使用该字典而不是以下内容。

config

如果我们需要全局使用__init__.py,那么我们会将变量放在/* Directive template */ <md-button class="md-button-toggle" ng-click="vm.toggle()"> {{ section.text | translate }} </md-button> <ul ng-show="isOpen()" class="menu-toggle-list"> <li ng-repeat="subItem in section.subItems"> {{ subItem.text | translate }} <menu-link section="subItem"></menu-link> </li> </ul> /* Directive Code */ ... return { restrict: 'AE', template, replace: true, scope: { section: '=', isOpen: '&' }, link(scope, element) { $timeout(() => { const $element = element; scope.vm.toggle = function () { console.log(scope.$parent.isOpen()); }; scope.isOpen = function () { return $element.isOpen(scope.section); }; scope.toggle = function () { $element.toggleOpen(scope.section); }; }); } } /* in your view, you can call controller fn */ <menu-toggle section="navItem" is-open="isOpen()" ng-if="navItem.type === 'toggle'"></menu-toggle> 的包的根目录中。这样我们就不用再阅读 app.conf 文件了。

我相信使用 app.conf 文件是有充分理由的。那是什么原因?

3 个答案:

答案 0 :(得分:1)

从配置文件中读取时,程序员可以选择如何处理文件格式化中的错误。无法解析特定的行?分配默认值。想要宽恕并接受没有收尾报价的字符串?去吧。

另一方面,Python模块全有或全无。如果文件的语法不完美,那么你什么也得不到

答案 1 :(得分:0)

因此,用户无需编辑源代码即可更改.conf文件中的值。还允许将设置保存到.conf并稍后阅读,而无需编辑源文件。

答案 2 :(得分:0)

安全。

我同意您的观点,但安全性无法处理 config.py,除非使用包装器,在这种情况下可以称为 config_parser.py

假设在您的代码中导入了 config.py

from config.dir import config

这一行执行 config.py

这意味着任何攻击者都可以在那里做任何事情,可能具有更高的权限。

我有足够的理由不这样做。


这是我的样板配置

class ConfigProvider(object):
    _config = None

    @staticmethod
    def get_config():
        if ConfigProvider._config is None:
            ConfigProvider._config = ConfigParser(config_path).parse()
        return ConfigProvider._config


class ConfigParser(object):
    def __init__(self, config_path):
        self._config_path = config_path

    def parse(self):
        parsed = None
        with open(self._config_path, 'r') as stream:
            try:
                # https://stackoverflow.com/questions/2352181/how-to-use-a-dot-to-access-members-of-dictionary
                parsed = Map(yaml.safe_load(stream))
            except yaml.YAMLError as exc:
                traceback.print_exc(exc)

        return parsed


class Map(dict):
    # https://stackoverflow.com/questions/2352181/how-to-use-a-dot-to-access-members-of-dictionary
    """
    Example:
    m = Map({'first_name': 'Eduardo'}, last_name='Pool', age=24, sports=['Soccer'])
    """
    def __init__(self, *args, **kwargs):
        super(Map, self).__init__(*args, **kwargs)
        for arg in args:
            if isinstance(arg, dict):
                for k, v in arg.items():
                    self[k] = v
                    if isinstance(v, dict):
                        self[k] = Map(v)

        if kwargs:
            # for python 3 use kwargs.items()
            for k, v in kwargs.items():
                self[k] = v
                if isinstance(v, dict):
                    self[k] = Map(v)

    def __getattr__(self, attr):
        return self.get(attr)

    def __setattr__(self, key, value):
        self.__setitem__(key, value)

    def __setitem__(self, key, value):
        super(Map, self).__setitem__(key, value)
        self.__dict__.update({key: value})

    def __delattr__(self, item):
        self.__delitem__(item)

    def __delitem__(self, key):
        super(Map, self).__delitem__(key)
        del self.__dict__[key]

    def __getstate__(self):  # required for successful pickling
        return self.__dict__

    def __setstate__(self, d):  # required for successful pickling
        self.__dict__.update(d)


config = ConfigProvider.get_config()

用户总是只需要一行就可以获取他们的配置。

当然不如 .py 方便,但安全性很重要。

注意 yaml 上的 safe_load