如何在Python中创建常量?
在Python中,如何声明一个常量?
在Java中,我们是这样做的:
public static final String CONST_NAME = "Name";
44 个回答
161
在Python中,语言本身并不会强制某些规则,而是大家约定了一些命名方式。例如,用__method
来表示私有方法,用_method
来表示受保护的方法。
同样的道理,你可以把常量的名字写成全大写,比如:
MY_CONSTANT = "one"
如果你希望这个常量永远不变,可以通过访问属性来做一些技巧,但更简单的方法是声明一个函数:
def MY_CONSTANT():
return "one"
唯一的问题是你在任何地方都需要使用MY_CONSTANT()
,不过通常来说,MY_CONSTANT = "one"
是Python中正确的写法。
你还可以使用namedtuple()来创建常量:
>>> from collections import namedtuple
>>> Constants = namedtuple('Constants', ['pi', 'e'])
>>> constants = Constants(3.14, 2.718)
>>> constants.pi
3.14
>>> constants.pi = 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
439
在其他编程语言中有一个叫做 const
的关键词,但在这里没有。不过,我们可以创建一个属性,这个属性有一个“获取函数”来读取数据,但没有“设置函数”来修改数据。这样就能保护这个标识符不被改变。
下面是使用类属性的另一种实现方式:
注意,这段代码对于想了解常量的读者来说并不简单。具体解释见下文。
def constant(f):
def fset(self, value):
raise TypeError
def fget(self):
return f()
return property(fget, fset)
class _Const(object):
@constant
def FOO():
return 0xBAADFACE
@constant
def BAR():
return 0xDEADBEEF
CONST = _Const()
print(hex(CONST.FOO)) # -> '0xbaadfaceL'
CONST.FOO = 0
##Traceback (most recent call last):
## File "example1.py", line 22, in <module>
## CONST.FOO = 0
## File "example1.py", line 5, in fset
## raise TypeError
##TypeError
代码解释:
- 定义一个函数
constant
,它接收一个表达式,并用这个表达式构建一个“获取函数”——这个函数只返回表达式的值。 - 设置函数会引发一个类型错误,所以它是只读的。
- 使用我们刚创建的
constant
函数作为装饰器,快速定义只读属性。
还有一些比较传统的方法:
(这段代码有点复杂,下面会有更多解释)
class _Const(object):
def FOO():
def fset(self, value):
raise TypeError
def fget(self):
return 0xBAADFACE
return property(**locals())
FOO = FOO() # Define property.
CONST = _Const()
print(hex(CONST.FOO)) # -> '0xbaadfaceL'
CONST.FOO = 0
##Traceback (most recent call last):
## File "example2.py", line 16, in <module>
## CONST.FOO = 0
## File "example2.py", line 6, in fset
## raise TypeError
##TypeError
- 要定义标识符 FOO,首先定义两个函数(fset 和 fget - 名字可以自己选)。
- 然后使用内置的
property
函数来构建一个可以“设置”或“获取”的对象。 - 注意
property
函数的前两个参数分别是fset
和fget
。 - 利用我们为自己的获取和设置函数选择的名字,创建一个关键字字典,使用 **(双星号)将所有本地定义的参数传递给
property
函数。
1363
在Python中,你不能把一个变量或值声明为常量。
为了让程序员知道某个变量是常量,通常会把它写成大写字母:
CONST_NAME = "Name"
如果想在常量被改变时抛出异常,可以参考Alex Martelli的Python常量。不过要注意,这种做法在实际中并不常见。
从Python 3.8开始,有一个typing.Final
的变量注解,可以告诉静态类型检查工具(比如mypy),你的变量不应该被重新赋值。这是最接近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