Python模块变量相互依赖

时间:2012-09-07 18:25:43

标签: python module config fabric

我正在尝试创建一个模块来保存Fabric文件的配置。此配置文件将保存与项目相关的设置,因此我可以为所有项目使用相同的fabfile。

我希望fabfile看起来像这样:

import config
from fabric.api import local

def deploy(env='staging'):
    config.env = env
    local("xcopy {project_dir} {deploy_target} /u /r /y".format(project_dir=config.project_dir, 
                                                                deploy_target=config.deploy_target))
    #Ok, this will be more involved than that, but it is enough to explain my problem

,配置文件如下所示:

env = 'staging'
project_dir = r'c:\some\unimportant\path'
deploy_target = r'c:\some\target\path\based\on\{env}'.format(env=env)

所以我可以使用: fab deployfab deploy:staging部署到登台环境,fab deploy:production部署到生产环境。

我想弄清楚的是当env变量发生变化时如何更新模块中的变量。

我希望我的配置文件尽可能简单,理想情况下,只需要变量赋值,但如果确实需要,我可以使用一些函数。设置文件中会有很多变量,所以使用global关键字更新函数中的值看起来真的很难看。

2 个答案:

答案 0 :(得分:0)

将配置参数存储在字典中。

因此,在一个__init__.py文件的目录中有一个名为my_config.py的文件(注意,这必须在你的python_path中),例如:

my_params = {'env': 'staging',
             'project_dir': r'c:\some\unimportant\path',
             'deploy_target': r'c:\some\target\path\based\on\staging',
            }

我不确定您打算如何将配置设置传递给fabfile,但是在配置文件中使用字典,访问您的设置非常简单。如果您拥有在单个字典中定义的单个项目的所有配置设置(如上所述),那么以下内容可能会出现在您的fabfile中:

config = __import__('my_config')

此时您可以使用以下方式访问配置设置:

env = config.my_params['env']

同样,我不完全确定你打算如何传递你正在寻找的配置,所以评论我是否错过了标记。在任何情况下,字典都是存储这类信息的pythonic方法,并且可以在需要时轻松导入这些值。

答案 1 :(得分:0)

我认为,只要您更改config,就会更新config.env模块中的变量,您将需要使用至少一个函数。

最简单的方法可能是将env作为变量删除,而是创建一个setEnv函数(将所有其他模块变量设置为适当的值)。另一个选择是离开env,但要调用函数来获取其他值(例如config.get_deploy_target())。

甚至可以使模块看起来只包含值,而实际上它们中的部分或全部是基于env或其他值动态计算的。这需要使用Python模块查找系统做一些技巧,这样你实际上是从类实例而不是实际模块中读取值。这允许使用config模块的代码很简单,但代价是使config.py本身更加复杂:

# config.py

class Config(object):
    def __init__(self):
        self.env = "staging"
        self.project_dir = r'c:\some\unimportant\path'

    @property
    def deploy_target(self):
        return r'c:\some\target\path\based\on\{env}'.format(env=self.env)

import sys
sys.modules["config"] = Config()