如何在Python中声明常量?
在Java中,我们做:
public static final String CONST_NAME = "Name";
如何在Python中声明常量?
在Java中,我们做:
public static final String CONST_NAME = "Name";
当前回答
在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
其他回答
你可以使用Tuple常量变量:
tuple是一个有序且不可更改的集合
my_tuple = (1, "Hello", 3.4)
print(my_tuple[0])
使用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 3.8之前,审计钩子可能是不可用的。
我基本上回答了另一个问题,结果和这个问题有关。它的思想是,你可以利用审计钩子来捕捉每一行的执行,解析代码对象,如果它满足某些条件(例如某个前缀并且已经定义过一次),你可以抛出一个错误。
你可能不得不支持其他赋值类型(例如,对于导入的东西,可能对于函数内部的局部变量,解包等),不使用全局变量,因为字典可以很容易地修改,实际上调查这是否安全,接受这个实现将对你的整个应用程序造成的性能损失,确保它在REPL之外工作,在ipython内部工作,等等等等。不管怎样,我们开始吧:
>>> import sys
>>> import ast
>>> import dis
>>> import types
>>>
>>>
>>> def hook(name, tup):
... if name == "exec" and tup:
... if tup and isinstance(tup[0], types.CodeType):
... code = tup[0]
... store_instruction_arg = None
... instructions = [dis.opname[op] for op in code.co_code]
...
... for i, instruction in enumerate(instructions):
... if instruction == "STORE_NAME":
... store_instruction_arg = code.co_code[i + 1]
... break
...
... if store_instruction_arg is not None:
... var_name = code.co_names[store_instruction_arg]
... if var_name in globals():
... raise Exception("Cannot re-assign variable")
...
>>>
>>> sys.addaudithook(hook)
>>>
>>> a = '123'
>>> a = 456
Traceback (most recent call last):
File "<stdin>", line 16, in hook
Exception: Cannot re-assign variable
>>>
>>> a
'123'
如果你以这种方式结束,你不应该,除了修复和泛化代码,你可能会想要找到一种方法,只让一些东西不变,例如,只有那些有特殊前缀的对象或只有对象有一些注释。
在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
PEP 591有“final”限定符。执行取决于类型检查器。
所以你可以这样做:
MY_CONSTANT: Final = 12407
注意:Final关键字仅适用于Python 3.8版本