使用命名元组作为事实上的常量——聪明还是愚蠢?

gvo*_*sey 9 python coding-style constants

我有 C# 背景,但现在使用 Python 3.x 进行大量科学计算工作,因此我想了解一下我的风格或口音按照 Python 标准有多“奇怪”。

特别是,Python 中没有这样的东西,这让我非常恼火const。我的用例是这样的:我正在保存*.npz文件(numpy 序列化数据字典)、传递字典、写入文件等,并且字典键、文件名等需要具有一致、可靠的命名模式。

很明显,在 8 个地方输入相同的神奇愚蠢字符串是错误的。

所以在我的模块根目录中,我有一个通常调用的文件base.py

import os
from collections import namedtuple
from os import path

# This is the tuple that contains operational constants
RuntimeConstants = namedtuple("Const", " ModelDirectoryLabelName \
                                  DefaultModelOutputDirectoryRoot \
                                  ResultDirectoryNameFormat \
                                  PeripheryOutputFilePrefix \
                                  NCOutputFilePrefix \
                                  SummaryPlotFileName \
                                  PeripheryConfigurationName \
                                  ResourceDirectoryName \
                                  StimulusTemplateName")

runtime_consts = RuntimeConstants(ModelDirectoryLabelName=".model-output-root",
                                  DefaultModelOutputDirectoryRoot="model-output",
                                  ResultDirectoryNameFormat="%d %b %y - %H%M",
                                  PeripheryOutputFilePrefix="periphery-output-",
                                  NCOutputFilePrefix="nc-output-",
                                  PeripheryConfigurationName="simulation-configuration.yaml",
                                  SummaryPlotFileName="summary-plots.pdf",
                                  ResourceDirectoryName="resources",
                                  StimulusTemplateName="default_stimulus.yaml"
                                  )
# This is the path of __this file__, which we can then base location on
rootPath = os.path.dirname(os.path.abspath(__file__))
Run Code Online (Sandbox Code Playgroud)

元组是不可变的;命名元组具有语义上有意义的标记,现在:

  • 我可以创建多个字典来动态传递数据,但知道它们的键是什么
  • 我可以使用已知的文件名和位置写入文件并检索文件。
  • 重构意味着我只需在一处修改一个神奇的字符串。
  • 即使安装了模块,我也知道我的目录在哪里。

在 C# 中,让一个或多个Constants类填充是很正常的做法public static const string Foo = "some magic string value";,所以这就是我在这里尝试重新创建的内容。

我目前有 4 个这样的namedtuples东西base.py,看起来已经快要太多了——但我不需要更多的东西了。它们在语义上都是不同的——我根据用法关联对常量进行分组。

这是常见的做法吗?

che*_*ner 0

它不是。常量的标准约定是仅使用全大写名称来表明该值是常量,并将它们记录为常量。

MODEL_DIRECTORY_LABEL_NAME = ".model-output-root"
DEFAULT_MODEL_OUTPUT_DIRECTORY_ROOT = "model-output"
# etc
Run Code Online (Sandbox Code Playgroud)

模块的用户修改这些值需要自行承担风险。

如果常量自然地与类相关联,则它们可以是类属性而不是模块级全局变量,但创建类只是为了对这些值进行分组的情况并不常见。