是否有用于使用类实例替换模块的有效用例?

时间:2013-02-01 10:15:21

标签: python

问题

是否有任何有效的用例用于ol'模块切换器,您可以用类实例替换模块?通过有效的用例,我的意思是一般会同意使用这个技巧是解决问题的最佳方式。例如,模块:

VERSION = (1, 2, 8)
VERSION_NAME = '1.2.8'

可以转换为:

import sys

class ConstantsModule(object):
    def __init__(self):
        self.VERSION = (1, 2, 8)

    @property
    def VERSION_NAME(self):
        return u'{}.{}.{}'.format(*self.VERSION)

sys.modules[__name__] = ConstantsModule()

现在VERSION_NAME是一个背后有逻辑的属性。

我没有发现任何相关信息,因此我搜索了这个。我在前一段时间读到的SO答案中学到了这个技巧,我知道这被称为“黑魔法”并且要避免,但我对有效的用例感到好奇。


我的具体用例

我的一个模块有一个小问题,如果模块是一个类实例,可以轻松解决。我有一个名为VERSION_NAME的“常量”,它是VERSION的字符串版本,而后者又是我的应用程序版本信息的元组。 VERSION_NAME在我的整个项目中以及基于此项目的其他几个项目中使用。现在我希望VERSION_NAME包含一些逻辑 - 我希望它基于VERSION,这样我就不必一直手动编辑它,我希望它被格式化根据几种环境情况略有不同。我看待它的方式我有两个选择:

  • 在我的项目及其所有子项目中查找VERSION_NAME的每个用例,并将其更改为get_version_name之类的函数调用。
  • 如上图所示调用黑魔法。

这个问题不是关于我的用例,这只是我认为可以用于

的一个例子。

1 个答案:

答案 0 :(得分:4)

由于Python中的所有内容都是一个对象,因此没有任何黑魔法;这只是鸭子打字;如果你创建一个像模块那样走路和说话的对象,那么Python的其余部分就更聪明了。

但是,对于您的特定用例,您不需要诉诸此级别的欺骗。只需在导入时计算版本名称:

VERSION_NAME = u'{}.{}.{}'.format(*VERSION)

没有任何地方声明模块全局变量只能是文字值;只需为它们使用Python表达式。

毕竟,您的VERSION_NAME变量在程序生命周期内不会发生变化,您只需要生成一次。仅在需要每次访问时需要重新计算的属性时才使用属性。