如何在Python中声明常量?
在Java中,我们做:
public static final String CONST_NAME = "Name";
如何在Python中声明常量?
在Java中,我们做:
public static final String CONST_NAME = "Name";
当前回答
你可以简单地:
STRING_CONSTANT = "hi"
NUMBER_CONSTANT = 89
希望这能让一切变得简单
其他回答
使用namedtuple有一种更干净的方法:
from collections import namedtuple
def make_consts(name, **kwargs):
return namedtuple(name, kwargs.keys())(**kwargs)
使用的例子
CONSTS = make_consts("baz1",
foo=1,
bar=2)
使用这种方法,您可以为常数命名空间。
您可以使用namedtuple作为一种变通方法来有效地创建一个常量,其工作方式与Java中的静态final变量(Java“常量”)相同。作为一种变通方法,它是优雅的。(更优雅的方法是简单地改进Python语言——什么样的语言可以让您重新定义math.pi?——但我跑题了。)
(当我写这篇文章时,我意识到这个问题的另一个答案提到了namedtuple,但我将在这里继续,因为我将展示一种更接近于您在Java中所期望的语法,因为不需要像namedtuple那样创建命名类型。)
跟着你的例子,你会记得在Java中,我们必须在某个类中定义常量;因为你没有提到类名,我们称它为Foo。下面是Java类:
public class Foo {
public static final String CONST_NAME = "Name";
}
这里是等效的Python。
from collections import namedtuple
Foo = namedtuple('_Foo', 'CONST_NAME')('Name')
我想在这里补充的关键点是,您不需要单独的Foo类型(“匿名命名元组”会很好,尽管这听起来有点矛盾),所以我们将命名元组命名为_Foo,这样它就不会转义到导入模块中。
这里的第二点是,我们立即创建了nametuple的一个实例,称其为Foo;没有必要在单独的步骤中执行此操作(除非您想这样做)。现在你可以做你在Java中可以做的事情:
>>> Foo.CONST_NAME
'Name'
但你不能给它赋值:
>>> Foo.CONST_NAME = 'bar'
…
AttributeError: can't set attribute
确认:我认为我发明了命名元组方法,但后来我看到其他人给出了类似的答案(尽管不那么紧凑)。然后我还注意到Python中的“命名元组”是什么?,这就指出了sys。version_info现在是一个命名元组,所以可能Python标准库早就提出了这个想法。
注意,不幸的是(这仍然是Python),你可以完全删除整个Foo赋值:
>>> Foo = 'bar'
(facepalm)
但至少我们阻止了福星。CONST_NAME值,这比什么都没有好。祝你好运。
PEP 591有“final”限定符。执行取决于类型检查器。
所以你可以这样做:
MY_CONSTANT: Final = 12407
注意:Final关键字仅适用于Python 3.8版本
您可以在下一个类的帮助下模拟常量变量。用法示例:
# Const
const = Const().add(two=2, three=3)
print 'const.two: ', const.two
print 'const.three: ', const.three
const.add(four=4)
print 'const.four: ', const.four
#const.four = 5 # a error here: four is a constant
const.add(six=6)
print 'const.six: ', const.six
const2 = Const().add(five=5) # creating a new namespace with Const()
print 'const2.five: ', const2.five
#print 'const2.four: ', const2.four # a error here: four does not exist in const2 namespace
const2.add(five=26)
当您希望启动一个新的常量名称空间时,请调用构造函数。注意,当Martelli的const类没有被修改时,这个类受到了保护,不受意外修改序列类型常量的影响。
来源如下。
from copy import copy
class Const(object):
"A class to create objects with constant fields."
def __init__(self):
object.__setattr__(self, '_names', [])
def add(self, **nameVals):
for name, val in nameVals.iteritems():
if hasattr(self, name):
raise ConstError('A field with a name \'%s\' is already exist in Const class.' % name)
setattr(self, name, copy(val)) # set up getter
self._names.append(name)
return self
def __setattr__(self, name, val):
if name in self._names:
raise ConstError('You cannot change a value of a stored constant.')
object.__setattr__(self, name, val)
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完全弃用。