如何在Python中声明常量?

在Java中,我们做:

public static final String CONST_NAME = "Name";

当前回答

PEP 591有“final”限定符。执行取决于类型检查器。

所以你可以这样做:

MY_CONSTANT: Final = 12407

注意:Final关键字仅适用于Python 3.8版本

其他回答

python声明“常量”的方式基本上是一个模块级别的变量:

RED = 1
GREEN = 2
BLUE = 3

然后编写类或函数。因为常量几乎都是整数,而且它们在Python中也是不可变的,所以你几乎没有机会改变它。

当然,除非显式地设置RED = 2。

在Python中创建常量的更好方法是从 优秀的attrs库,这很有帮助 Python程序员创建类时不使用样板文件。的 Short-con package也有同样的功能 常量,提供一个方便的包装器 attr.make_class。[声明:我是short-con的作者。]

值可以通过dict或kwargs显式声明 例子也有同样的作用。常量()函数支持的所有特性 库和cons()是简单使用kwarg的辅助程序。

from short_con import constants, cons

Pieces = constants('Pieces', dict(king = 0, queen = 9, rook = 5, bishop = 3, knight = 3, pawn = 1))
Pieces = cons('Pieces', king = 0, queen = 9, rook = 5, bishop = 3, knight = 3, pawn = 1)

的值相同(或可以从其导出)的情况 属性名,使用更加紧凑。只提供名称作为 空格分隔的字符串、列表或元组。

NAMES = 'KING QUEEN ROOK BISHOP KNIGHT PAWN'
xs = NAMES.split()

Pieces = constants('Pieces', NAMES)      # All of these do the same thing.
Pieces = constants('Pieces', xs)
Pieces = constants('Pieces', tuple(xs))

基于名称的用法支持一些风格约定:大写或 小写的属性名,以及枚举样式的值。

方法创建的常量不同,底层值可以直接访问 内置枚举库:

Pieces.QUEEN        # short-con usage
Pieces.QUEEN.value  # enum library usage

对象直接可迭代,可转换为其他集合:

for name, value in Pieces:
    print(name, value)

d = dict(Pieces)
tups = list(Pieces)

使用namedtuple有一种更干净的方法:

from collections import namedtuple


def make_consts(name, **kwargs):
    return namedtuple(name, kwargs.keys())(**kwargs)

使用的例子

CONSTS = make_consts("baz1",
                     foo=1,
                     bar=2)

使用这种方法,您可以为常数命名空间。

我正在尝试用不同的方法在Python中创建一个真正的常量,也许我找到了漂亮的解决方案。

例子:

为常量创建容器

>>> DAYS = Constants(
...     MON=0,
...     TUE=1,
...     WED=2,
...     THU=3,
...     FRI=4,
...     SAT=5,
...     SUN=6
... )   

从容器中获取价值

>>> DAYS.MON
0
>>> DAYS['MON']
0  

用纯python数据结构表示

>>> list(DAYS)
['WED', 'SUN', 'FRI', 'THU', 'MON', 'TUE', 'SAT']
>>> dict(DAYS)
{'WED': 2, 'SUN': 6, 'FRI': 4, 'THU': 3, 'MON': 0, 'TUE': 1, 'SAT': 5}

所有常数都是不可变的

>>> DAYS.MON = 7
...
AttributeError: Immutable attribute

>>> del DAYS.MON 
...
AttributeError: Immutable attribute

仅对常量自动补全

>>> dir(DAYS)
['FRI', 'MON', 'SAT', 'SUN', 'THU', 'TUE', 'WED']

像list.sort那样排序

>>> DAYS.sort(key=lambda (k, v): v, reverse=True)
>>> list(DAYS)
['SUN', 'SAT', 'FRI', 'THU', 'WED', 'TUE', 'MON']

与python2和python3的兼容性

常量的简单容器

from collections import OrderedDict
from copy import deepcopy

class Constants(object):
    """Container of constant"""

    __slots__ = ('__dict__')

    def __init__(self, **kwargs):

        if list(filter(lambda x: not x.isupper(), kwargs)):
            raise AttributeError('Constant name should be uppercase.')

        super(Constants, self).__setattr__(
            '__dict__',
            OrderedDict(map(lambda x: (x[0], deepcopy(x[1])), kwargs.items()))
        )

    def sort(self, key=None, reverse=False):
        super(Constants, self).__setattr__(
            '__dict__',
            OrderedDict(sorted(self.__dict__.items(), key=key, reverse=reverse))
        )

    def __getitem__(self, name):
        return self.__dict__[name]

    def __len__(self):
        return  len(self.__dict__)

    def __iter__(self):
        for name in self.__dict__:
            yield name

    def keys(self):
        return list(self)

    def __str__(self):
        return str(list(self))

    def __repr__(self):
        return '<%s: %s>' % (self.__class__.__name__, str(self.__dict__))

    def __dir__(self):
        return list(self)

    def __setattr__(self, name, value):
        raise AttributeError("Immutable attribute")

    def __delattr__(*_):
        raise AttributeError("Immutable attribute")

Python没有常量。

也许最简单的替代方法是为它定义一个函数:

def MY_CONSTANT():
    return 42

MY_CONSTANT()现在拥有常量的所有功能(加上一些讨厌的大括号)。