0

问题

ol' 模块 switcheroo是否有任何有效的用例,您将模块替换为类实例?我所说的有效用例是指普遍认为使用此技巧是解决问题的最佳方法的情况。例如,模块:

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.
  • 如上所示调用黑魔法。

这个问题与我的用例无关,这只是我认为它可以用于什么的一个例子。

4

1 回答 1

4

由于 Python 中的一切都是对象,所以它没有什么黑魔法。这只是鸭子打字;如果你创建一个像模块一样走路和说话的对象,那么 Python 的其余部分就不会更明智了。

但是,对于您的特定用例,您无需诉诸这种程度的欺骗。只需在导入时计算版本名称:

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

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

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

于 2013-02-01T10:21:47.087 回答