实际开发中我们经常会碰到需要定义常量的情形,c语言提供了const关键字来实现,但是python本身却没有提供const,要想在python代码中定义常量,需要我们自己来实现。
下面定义一个const类。要求符合“命名全部为大写”和“值一旦绑定便不可再修改”这两个条件。代码
class const(object):
class ConstError(TypeError):
pass
class ConstCaseError(ConstError):
pass
def __setattr__(self, name, value):
if self.__dict__.has_key(name):
raise self.ConstError, "can't change const.%s" % name
if not name.isupper():
raise self.ConstCaseError, "const name '%s' is not all uppercase" % name
self.__dict__[name] = value
import sys
sys.modules[__name__] = const()
这里通过对常量对应的值进行修改时或者命名不符合规范时抛出异常来满足以上常量的两个条件。
###NOTE
使用sys.modules[name]可以获取一个模块对象,并可以通过该对象获取模块的属性,这儿使用了sys.modules向系统字典注入了一个const对象从而实现了在执行import const时实际获取了一个const实例的功能,sys.module在文档中的描述如下:
sys.modules
This is a dictionary that maps module names to modules which have already been loaded. This can be manipulated to force reloading of modules and other tricks. Note that removing a module from this dictionary is not the same as calling reload() on the corresponding module object.
sys.modules[name] = const()这行代码将系统已经加载的模块列表中的const替换为了const(),即一个const实例
##使用
整个工程需要使用的常量都应该定义在一个文件中。例如你将const.py放在了project.utils目录下,常量被定义在project.apps目录下的project_consts.py文件中,那么应该这么写:
#project_consts.py
from project.utils import const
const.NAME = 'IBM'
const.EMAIL = 'ibm.com'
在其他文件中需要使用这些常量时,用如下方式调用:
from project.apps.project_consts import const
print const.NAME