一个用于整个python应用程序的配置文件

一个用于整个python应用程序的配置文件,python,import,module,config,Python,Import,Module,Config,我对Python有点陌生(但对编程一点也不熟悉,已经精通Perl、PHP和Ruby)。 我遇到了以前所有语言与Python之间的一个主要区别:主要是我可以轻松地将另一个文件中的数据读入整个项目。 我想解决两个主要的例子: 1) 我希望有一个settings/config文件(在YAML中),可以在config.py文件中读取和解析。然后,我希望生成的dict()可以被项目中的所有其他文件访问。我已经通过lib.project.config import cfg中的找到了实现方法,但这意味着对于导

我对Python有点陌生(但对编程一点也不熟悉,已经精通Perl、PHP和Ruby)。 我遇到了以前所有语言与Python之间的一个主要区别:主要是我可以轻松地将另一个文件中的数据读入整个项目。 我想解决两个主要的例子:

1) 我希望有一个settings/config文件(在YAML中),可以在config.py文件中读取和解析。然后,我希望生成的dict()可以被项目中的所有其他文件访问。我已经通过lib.project.config import cfg中的
找到了实现方法,但这意味着对于导入配置的每个页面,系统都必须重新分析yaml。我觉得那太傻了。难道没有办法只解析该文件一次,然后让我的项目中的任何其他文件都可以访问结果吗

2) 我想导入一个database.py文件,然后查看我的配置,看看是否需要导入数据库类的sqlite3、mysql或postgresql版本。同样,我可以通过将逻辑直接放在我需要数据库类的每个页面中来管理这一点。但我讨厌像这样粘贴代码

if cfg.get('db_type') == 'sqlite':
    from lib.project.databases.sqlite3 import database
elif cfg.get('db_type') == 'mysql':
    from lib.project.databases.mysql import database
在每个需要数据库类的文件的顶部。我想补充一点:

import lib.project.database
任何帮助都将不胜感激。 我做了很多谷歌搜索,所以没有找到我的答案。希望你们中的一个能帮上忙

谢谢

更新: 我这样做的原因(对于#2)是因为我还试图让其他类继承数据库类。 因此lib/project/databases/sqlite.py是数据库类的定义。 lib/project/databases/mysql.py也是如此。 这样做的目的是,在完成此导入后,我可以导入像users类这样的类,并这样定义它:

class user(database):
    ...
从而继承数据库类的所有结构和方法。 您的建议是,只需基于sqlite/mysql逻辑/决策创建一个实例,然后将其传递到需要的位置,这是一个很好的解决方案。但我还需要一点。。。 想法?

1)您都准备好了-文件只会被读取一次

2) 同意您不想复制任何这样的粘贴代码-如果您想在整个项目中使用数据库的一个实例,您可以执行以下操作:

import lib.project

db = lib.project.database
其中
db
只是一个局部变量,用于访问已创建的数据库。您可以在
lib/project/databases.py
中将数据库实例化为
database
(使用
if/elif
code解析是否使用sqlite3或mysql),然后在
lib/project/\uuu init\uuuuuuu.py
文件中执行从.databases导入数据库的

如果希望在整个项目中使用多个数据库(相同的sqlite3/mysql类型),则需要在
databases.py中解析绑定到(或继承自)数据库的构造函数

from lib.project.Config import config
if config.db_type == 'sqlite' :
    import lib.project.databases.Sqlite as Db
elif config.db_type == 'mysql':
    import lib.project.databases.Mysql as Db

class Database(Db):
    '''docs'''

感谢大家帮助我了解更多关于Python的知识,以及如何完成我的目标

以下是我最后做的:

1)配置文件问题: 这显然从一开始就基本解决了。我证实了每个人都在说的话:你可以随意多次“导入”一个文件,但它只能被解析/处理/编译一次。至于让任何需要它的文件都可以访问它: 配置类:

import os
import yaml

class Config:

    def __init__(self):
        self.path = os.getcwd()
        stream = open(self.path+"/conf/config.yaml", 'r')
        data = yaml.load(stream)
        config_keys = data.keys()
        for k in config_keys:
            setattr(self, k, data.get(k))
        if (os.path.isfile(self.path+"/conf/config-override.yaml") ):
            stream = open(self.path+"/conf/config-override.yaml", 'r')
            data = yaml.load(stream)
            config_keys = data.keys()
            for k in config_keys:
                setattr(self, k, data.get(k))

config = Config()
然后是任何想要使用它的文件:

from lib.project.Config import config
到目前为止,一切都进展顺利

2) 数据库类的动态数据库类型: 我只是稍微改变了一下我的总体设计,使数据库类(大部分为空)继承自Sqlite或Mysql类(这两种自定义构建都是现有Sqlite3和Mysql连接器类的包装)。这样,总是有一个可靠的数据库类可从中继承,我只加载需要的文件,所有这些都由我的配置文件定义。例子: 数据库类:

from lib.project.Config import config
if config.db_type == 'sqlite' :
    from lib.project.databases.Sqlite import Sqlite
elif config.db_type == 'mysql':
    from lib.project.databases.Mysql import Mysql

class Database(Sqlite if config.db_type == 'sqlite' else Mysql):
''' documentation '''
我仍然希望听到人们对这个代码/方法的反馈。 正如我所说的,我对Python还不熟悉,可能还缺少一些东西


再次感谢各位。

模块并非每次导入时都执行。第一次导入的结果保存在
sys.modules
字典中。在同一模块的后续导入中,只返回缓存的值,而不是再次运行它。这意味着,如果读取模块主代码中的配置文件并将结果保存在全局模块变量中,则只会发生一次。给定模块的所有导入程序都可以简单地引用其中包含结果的变量(或引用这样做的模块函数)。感谢@maartineau,请澄清:这是否意味着我仍然需要导入配置文件以及每个需要它的文件(理解为它实际上并不是每次都被重新解析)?如果我必须导入每个文件,这并不是什么大不了的事,只是看起来太过分了。在只导入顶部文件之后,您希望在每页上执行类似配置设置['path']的操作。如果您导入了
config
,那么您应该可以引用
config.settings['path']
,假设在运行模块时在模块的顶层定义了
settings
字典(这很容易做到)。您可以使事情看起来像是内置的-
导入
甚至不需要-,但不鼓励这样做。我会更进一步,将db类的实例化放在库模块中,只需导入实例即可。谢谢各位。如果我只需要数据库类的实例,这将是一个很好的解决方案…:(我这样做的原因(对于#2)是因为我还试图让其他类继承数据库类。有关更多详细信息,请参阅我更新的问题。请参阅我对#2的回答中的编辑。虽然#1看起来不错,但我建议使用模块的小写名称(
config.py
而不是
config.py
),我