Python 中创建常量的惯例

23 投票
5 回答
28550 浏览
提问于 2025-04-16 23:41

我正在写一个应用程序,需要找出不同数据库引擎的结构信息。为此,我决定用Python写一个小的数据库适配器。我首先写了一个基础类,定义了我需要的功能,然后再用继承这个基础类的其他类来实现这些功能。在这个过程中,我需要实现一些常量,这些常量需要在所有这些类中都能访问到。其中一些常量需要用C语言那种位运算的方式进行组合。

我想问的是,

  1. 分享这些常量的标准方法是什么?
  2. 创建可以组合的常量的正确方法是什么?我指的是像MAP_FIXED | MAP_FILE | MAP_SHARED这样的C语言代码。

关于第一个问题,我看到有些讨论提到把所有常量先放到一个模块里。对于第二个问题,我简单想过用一个布尔值的字典。但这两种方法看起来都太麻烦了。我想这应该是一个比较常见的需求,肯定有更好的解决办法!

5 个回答

4

标准库是一个很棒的知识来源,想要的例子可以在doctest代码中找到:

OPTIONS = {}

# A function to add (register) an option.
def register_option(name):
    return OPTIONS.setdefault(name, 1 << len(OPTIONS))

# A function to test if an option exist.
def has_option(options, name):
    return bool(options & name)

# All my option defined here.
FOO = register_option('FOO')
BAR = register_option('BAR')
FOOBAR = register_option('FOOBAR')


# Test if an option figure out in `ARG`.
ARG = FOO | BAR
print has_option(ARG, FOO)
# True
print has_option(ARG, BAR)
# True
print has_option(ARG, FOOBAR)
# False

注意:re模块也使用位运算的参数风格,如果你想要另一个例子的话。

18

常量通常放在模块的最上面。根据PEP 8的规定:

常量

常量一般是在模块的层级上定义的,名字全部用大写字母,并用下划线来分隔单词。比如说,MAX_OVERFLOW和TOTAL就是常量的例子。

如果你想在类里面使用常量,可以把它们定义为类的属性。

22

分享这些常量的标准方法是什么?

在标准库中,最常见的方法是把常量定义为模块级别的变量,名称使用全大写并用下划线分隔。

创建可以组合的常量的正确方法是什么?我指的是C语言中允许的MAP_FIXED | MAP_FILE | MAP_SHARED这样的代码。

在这里,和C语言的规则是一样的。你需要确保每个常量值对应一个唯一的位,也就是2的幂(2, 4, 8, 16,等等)。

大多数情况下,人们会使用十六进制数字来表示这些常量:

OPTION_A = 0x01
OPTION_B = 0x02
OPTION_C = 0x04
OPTION_D = 0x08
OPTION_E = 0x10
# ...

有些人更喜欢一种更易读的风格,使用位移运算符动态计算常量值:

OPTION_A = 1 << 0
OPTION_B = 1 << 1
OPTION_C = 1 << 2
# ...

在Python中,你也可以使用二进制表示法来让这一点更加明显:

OPTION_A = 0b00000001
OPTION_B = 0b00000010
OPTION_C = 0b00000100
OPTION_D = 0b00001000

不过,由于这种表示法比较冗长且难以阅读,使用十六进制或二进制位移表示法可能更好。

撰写回答