Python中存在常量吗?相信很多人的答案是否定的。
实际上Python的内建命名空间是 支持一小部分常量的,
如 True
、 False
、 None
等,只是Python没有提供定义常量的直接方式而已。
使用常量的方式
那么,在Python中应该如何使用常量呢? 一般来说有以下两种方式:
- 通过命名风格来提醒使用者该变量代表的意义为常量,
如常量名所有字母大写,用下划线连接各个单同,如
MAX_OVERFLOW
、TOTAL
。 然而这种方式并没有实现真正的常量,其对应的值仍然可以改变,这只是一种约定俗成的风格。 - 通过自定义的类实现常量功能。这要求符合“命名全部为大写"和“值一旦绑定便不可再修改”这两个条件。 下面是一种较为常见的解决方法,它通过对常量对应的值进行修改时或者命名不符合规范时抛出异常来满足以上常量的两个条件。
class _const:
class ConstError(TypeError): pass
class ConstCaseError(ConstError): pass
def __setattr__(self, name, value):
if name in self.__dict__:
raise self.ConstError( "Can't change const.%s" % name )
if not name.isupper():
raise self.ConstCaseErrorf( " const name '%s' is not all uppercase" % name)
self.__dict__[name]= value
import sys
sys.modules[__name__]=_const()
如果上面的代码对应的模块名为 const2
,写在一个const2.py
文件里, 使用的时候只需要 import const2
,
便可以直接定义常量了,如以下代码:
import const2
const2.COMPANY = "IBM"
上面的代码中常量一旦赋值便不可再更改。
因此 const2.COMPANY = "SAP"
会拋出 const.ConstError
异常;
而常量名称如果小写,如 const2.name = "Python"
,也会拋出 const.ConstCaseError
异常。
无论采用哪一种方式来实现常量,都提倡将常量集中到一个文件中,因为这样有利于维护。
一旦需要修改常量的值,可以集中统一进行,而不是逐个文件去检查。
采用第二种方式实现的常量可以这么做:将存放常量的文件命名为 constant.py
,并在其中定义一系列常量。
class _const:
class ConstError(TypeError): pass
class ConstCaseError(ConstError): pass
def __setattr__(self, name, value):
if name in self.__dict__:
raise self.ConstError( "Can't change const.%s" % name )
if not name.isupper():
raise self.ConstCaseErrorf( " const name '%s' is not all uppercase" % name)
self.__dict__[name]= value
import sys
sys.modules[__name__]=_const()
sys.modules.get('const')
import const2
const2.MY_CONSTANT =1
const2.MY_SECOND_CONSTANT = 2
const2.MY_THIRD_CONSTANT = 'a'
const2.MY_FORTH_CONSTANT = 'b'
当在其他模块中引用这些常量时,按照如下方式进行即可:
import const2
print(const2.MY_SECOND_CONSTANT )
2
print(const2.MY_THIRD_CONSTANT * 2 )
aa
print(const2.MY_FORTH_CONSTANT+'5' )
b5