global-variables - 在 config.py 中提供全局配置变量的大多数 Pythonic 方式?

标签 global-variables python config egg

在将简单的东西过度复杂化的无尽探索中,我正在研究最“Pythonic”的方法,以在 Python egg 包中的典型“config.py”中提供全局配置变量。

传统方式(aah, good ol' #define!)如下:

MYSQL_PORT = 3306
MYSQL_DATABASE = 'mydb'
MYSQL_DATABASE_TABLES = ['tb_users', 'tb_groups']

因此,全局变量通过以下方式之一导入:

from config import *
dbname = MYSQL_DATABASE
for table in MYSQL_DATABASE_TABLES:
    print table

或:

import config
dbname = config.MYSQL_DATABASE
assert(isinstance(config.MYSQL_PORT, int))

这是有道理的,但有时可能会有点困惑,尤其是当您尝试记住某些变量的名称时。此外,提供'配置'对象,以变量作为属性,可能更灵活。所以,在 bpython config.py 文件的引导下,我想出了:

class Struct(object):

    def __init__(self, *args):
        self.__header__ = str(args[0]) if args else None

    def __repr__(self):
        if self.__header__ is None:
             return super(Struct, self).__repr__()
        return self.__header__

    def next(self):
        """ Fake iteration functionality.
        """
        raise StopIteration

    def __iter__(self):
        """ Fake iteration functionality.
        We skip magic attribues and Structs, and return the rest.
        """
        ks = self.__dict__.keys()
        for k in ks:
            if not k.startswith('__') and not isinstance(k, Struct):
                yield getattr(self, k)

    def __len__(self):
        """ Don't count magic attributes or Structs.
        """
        ks = self.__dict__.keys()
        return len([k for k in ks if not k.startswith('__')\
                    and not isinstance(k, Struct)])

还有一个 'config.py' 导入类,内容如下:

from _config import Struct as Section

mysql = Section("MySQL specific configuration")
mysql.user = 'root'
mysql.pass = 'secret'
mysql.host = 'localhost'
mysql.port = 3306
mysql.database = 'mydb'

mysql.tables = Section("Tables for 'mydb'")
mysql.tables.users = 'tb_users'
mysql.tables.groups =  'tb_groups'

并以这种方式使用:

from sqlalchemy import MetaData, Table
import config as CONFIG

assert(isinstance(CONFIG.mysql.port, int))

mdata = MetaData(
    "mysql://%s:%s@%s:%d/%s" % (
         CONFIG.mysql.user,
         CONFIG.mysql.pass,
         CONFIG.mysql.host,
         CONFIG.mysql.port,
         CONFIG.mysql.database,
     )
)

tables = []
for name in CONFIG.mysql.tables:
    tables.append(Table(name, mdata, autoload=True))

这似乎是一种在包内存储和获取全局变量的更具可读性、表现力和灵 active 的方式。

有史以来最糟糕的想法?应对这些情况的最佳做法是什么? 你的在你的包中存储和获取全局名称和变量的方式是什么?

最佳答案

像这样使用内置类型怎么样:

config = {
    "mysql": {
        "user": "root",
        "pass": "secret",
        "tables": {
            "users": "tb_users"
        }
        # etc
    }
}

您可以按如下方式访问这些值:

config["mysql"]["tables"]["users"]

如果您愿意牺牲在配置树中计算表达式的潜力,您可以使用 YAML最终得到一个更具可读性的配置文件,如下所示:

mysql:
  - user: root
  - pass: secret
  - tables:
    - users: tb_users

并使用像 PyYAML 这样的库方便地解析和访问配置文件

关于global-variables - 在 config.py 中提供全局配置变量的大多数 Pythonic 方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6198372/

相关文章:

python 数据透视表 - 列是日期,应该正确排序

当我使用wx时Python : datetime. strptime错误

c# - 得到一个错误,可能是WebResource.axd

perl - 分层和可继承配置的最佳 Perl 模块是什么?

python - 旗鱼 : how to run on computer without gpu

lua - Nvim-cmp 多次添加相同的源

python - 将局部变量转换为全局变量

c++ - C++ DLL 中全局变量的范围是什么

scope - cmake,迷失在全局变量的概念中(以及 PARENT_SCOPE 或 add_subdirectory 替代方案)

Python 全局列表未更新