在config.py中提供全局配置变量的大多数Pythonic方法? [英] Most Pythonic way to provide global configuration variables in config.py?
问题描述
在对过于简单的东西的无尽追求中,我正在研究在Python egg软件包中典型的 config.py 中提供全局配置变量的'Pythonic'方法。
$ b 传统的方式(aah,good ol'#define !)如下所示:
MYSQL_PORT = 3306
MYSQL_DATABASE ='mydb'
MYSQL_DATABASE_TABLES = ['tb_users','tb_groups']
因此,可以通过以下方式之一导入全局变量:
from config import *
dbname = MYSQL_DATABASE
for MYSQL_DATABASE_TABLES:
print table
或:
$ p $ 导入配置
dbname = config.MYSQL_DATABASE
assert(isinstance(config.MYSQL_PORT,int))
它是有道理的,但有时可以是有点混乱,特别是当你试图记住某些变量的名字时。此外,提供一个'配置'对象,变量作为属性可能更加灵活。所以,从 bpython config.py文件中领先,我想出了:
class Struct (object):
$ b $ def __init __(self,* args):
self .__ header__ = str(args [0])如果其他参数无
def __repr__ (self):
if self .__ header__ is None:
return super(Struct,self).__ repr __()
return self .__ header__
def next(self ):
假迭代功能
提升StopIteration
def __iter __(self):
假迭代功能
我们跳过魔术属性和结构,然后返回其余的
ks = self .__ dict __。keys()
for k in ks:
如果不是k.startswith('__')而不是isinstance(k,Struct):
yield getattr(self,k)
def __len __(self):
不要统计魔术属性或结构。
ks = self .__ dict __。keys()
return len([k for k in ks if k.startswith('__')\
and not isinstance(k,Struct)])
和一个导入类的'config.py',内容如下:
from _config导入Struct作为Section
$ b $ mysql = Section(MySQL特定配置)
mysql.user = 'root'
mysql.pass ='secret'
mysql.host ='localhost'
mysql.port = 3306
mysql.database ='mydb'
mysql.tables = Section(mydb'的表)
mysql.tables.users ='tb_users'
mysql.tables.groups ='tb_groups'
并以这种方式使用:
导入配置为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 = []
在CONFIG.mysql.tables中的名称:
tables.append(表(名称,mdata,autoload = True))
这似乎是一个更具可读性,表达性和灵活性的方式来存储和获取包中的全局变量。
有史以来最蠢的想法?应对这些情况的最佳做法是什么?什么是你的方式来存储和获取你的包中的全局名称和变量?解决方案那一次。最终,我发现我的简化 basicconfig.py 足以满足我的需求需要。如果需要,您可以传入其他对象的名称空间以供它参考。您也可以传入代码中的其他默认值。它还将属性和映射样式语法映射到相同的配置对象。
In my endless quest in over-complicating simple stuff, I am researching the most 'Pythonic' way to provide global configuration variables inside the typical 'config.py' found in Python egg packages.
The traditional way (aah, good ol' #define!) is as follows:
MYSQL_PORT = 3306 MYSQL_DATABASE = 'mydb' MYSQL_DATABASE_TABLES = ['tb_users', 'tb_groups']
Therefore global variables are imported in one of the following ways:
from config import * dbname = MYSQL_DATABASE for table in MYSQL_DATABASE_TABLES: print table
or:
import config dbname = config.MYSQL_DATABASE assert(isinstance(config.MYSQL_PORT, int))
It makes sense, but sometimes can be a little messy, especially when you're trying to remember the names of certain variables. Besides, providing a 'configuration' object, with variables as attributes, might be more flexible. So, taking a lead from bpython config.py file, I came up with:
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)])
and a 'config.py' that imports the class and reads as follows:
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'
and is used in this way:
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))
Which seems a more readable, expressive and flexible way of storing and fetching global variables inside a package.
Lamest idea ever? What is the best practice for coping with these situations? What is your way of storing and fetching global names and variables inside your package?
解决方案I did that once. Ultimately I found my simplified basicconfig.py adequate for my needs. You can pass in a namespace with other objects for it to reference if you need to. You can also pass in additional defaults from your code. It also maps attribute and mapping style syntax to the same configuration object.
这篇关于在config.py中提供全局配置变量的大多数Pythonic方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!