【问题标题】:Python module variable interdependencyPython模块变量相互依赖
【发布时间】:2012-09-07 18:25:42
【问题描述】:

我正在尝试创建一个模块来保存 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 deploy 或 fab deploy:staging 部署到暂存环境,fab deploy:production 部署到生产环境。

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

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

【问题讨论】:

  • 部署时是否需要永久更改配置文件,或者部署完成后恢复默认值是否可以?后者应该很容易,但前者要复杂得多。
  • 配置文件在每个项目的基础上都是唯一的。 config.py 模块中的设置几乎是一成不变的。他们不会经常改变。每个项目通常只有 2-3 个环境。路径非常相似,只是改变了几个字符,有时是服务器名称,但仅此而已。
  • 部署后返回默认值是可以的,因为 fabfile 中的所有命令都将采用 env 参数,该参数将在配置模块中相应地设置值(如果我设法实现我的目标尝试做)。

标签: python module config fabric


【解决方案1】:

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

因此,在带有 __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']

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

【讨论】:

  • 目前,我有一个名为 Deploy 的文件夹,其中包含 fabfile.py 和 config.py。这个文件夹将被复制到我们拥有的每个项目中。当我们创建一个新项目时,只需要更新 config.py 文件。我想要做的是能够在 fabfile 中调用import config。导入配置模块后,我希望能够通过调用config.env = 'environment_name' 来设置环境。更改 config.env 的值应该会更新 config 模块中依赖于该值的所有设置的值。
  • 我不希望每个环境都有一个字典。
  • 好的,我想我明白你在说什么了。我将坚持使用字典是做你想做的最简单的方法。最大的变化是您必须使用括号语法而不是点语法来访问您的配置设置。如果你想走一条没有字典的路线,你将使用我认为是黑客的东西。您不想使用字典有什么具体原因吗?
  • 配置文件可能由非python程序员维护,所以它必须尽可能简单。使用 dict,我不必为每个项目的每个环境维护一个 dict 吗?
【解决方案2】:

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

最简单的方法可能是将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()

【讨论】:

    猜你喜欢
    • 2013-04-06
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 2011-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-18
    相关资源
    最近更新 更多