如何在Python中声明常量?
在Java中,我们做:
public static final String CONST_NAME = "Name";
如何在Python中声明常量?
在Java中,我们做:
public static final String CONST_NAME = "Name";
当前回答
from enum import Enum
class StringConsts(str,Enum):
ONE='one'
TWO='two'
print(f'Truth is {StringConsts.ONE=="one"}') #Truth is True
StringConsts.ONE="one" #Error: Cannot reassign
Enum和str的混合让你不必重新实现setattr(通过Enum),也不必与其他str对象进行比较(通过str)。
这可能会使http://code.activestate.com/recipes/65207-constants-in-python/?in=user-97991完全弃用。
其他回答
下面是一个“Constants”类的实现,它创建具有只读(常量)属性的实例。例如,可以使用Nums。PI来获得一个已初始化为3.14159的值,Nums。PI = 22引发异常。
# ---------- Constants.py ----------
class Constants(object):
"""
Create objects with read-only (constant) attributes.
Example:
Nums = Constants(ONE=1, PI=3.14159, DefaultWidth=100.0)
print 10 + Nums.PI
print '----- Following line is deliberate ValueError -----'
Nums.PI = 22
"""
def __init__(self, *args, **kwargs):
self._d = dict(*args, **kwargs)
def __iter__(self):
return iter(self._d)
def __len__(self):
return len(self._d)
# NOTE: This is only called if self lacks the attribute.
# So it does not interfere with get of 'self._d', etc.
def __getattr__(self, name):
return self._d[name]
# ASSUMES '_..' attribute is OK to set. Need this to initialize 'self._d', etc.
#If use as keys, they won't be constant.
def __setattr__(self, name, value):
if (name[0] == '_'):
super(Constants, self).__setattr__(name, value)
else:
raise ValueError("setattr while locked", self)
if (__name__ == "__main__"):
# Usage example.
Nums = Constants(ONE=1, PI=3.14159, DefaultWidth=100.0)
print 10 + Nums.PI
print '----- Following line is deliberate ValueError -----'
Nums.PI = 22
感谢@MikeGraham的FrozenDict,我将其作为一个起点。更改后,使用语法不再是Nums['ONE'],而是Nums.ONE。
感谢@Raufio的回答,对于覆盖__ setattr __的想法。
或者要了解更多功能的实现,请参阅@Hans_meine的实现 named_constants在GitHub
在Python中,不能将变量或值声明为常量。
为了让程序员知道变量是常量,通常用大写:
CONST_NAME = "Name"
要在常量发生变化时引发异常,请参阅Alex Martelli的《Python中的常量》。注意,这在实践中并不常用。
从Python 3.8开始,有一个类型。最后一个变量注释,它将告诉静态类型检查器(如myypy)您的变量不应该被重新分配。这是最接近于Java的final。然而,它实际上并不能阻止重新分配:
from typing import Final
a: Final[int] = 1
# Executes fine, but mypy will report an error if you run mypy on this:
a = 2
我使用冻结数据类声明常量值,如下所示:
from dataclasses import dataclass
@dataclass(frozen=True)
class _Const:
SOME_STRING = 'some_string'
SOME_INT = 5
Const = _Const()
# In another file import Const and try
print(Const.SOME_STRING) # ITS OK!
Const.SOME_INT = 6 # dataclasses.FrozenInstanceError: cannot assign to field 'SOME_INT'
在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)
你可以使用StringVar或IntVar等,你的常量是const_val
val = 'Stackoverflow'
const_val = StringVar(val)
const.trace('w', reverse)
def reverse(*args):
const_val.set(val)