众所周知,在Python中其实并没有一个严格定义的常量概念。目前所采用的常用约定俗成的方式是采用命名全为大写字母的方式来标识别常量。但实际上这种方式并不能起到防止修改的功能,而只是从语义和可读性上做了区分。
那么,应该怎么实现一个简单的常量呢?
这个就需要借助于Python里的面向对象的实现和描述符(值得一提的是,在Python最新版本3.6中,进一步完善了描述符的功能,PEP 487: Descriptor Protocol Enhancements)。
话不多说,先出代码,再说原理:
class ConstValue(object):
class ConstError(TypeError):
pass
class ConstCaseError(ConstError):
pass
def __setter__(self, name, value):
if self.__dict__.has_key(name):
raise self.ConstError, 'Not allowed change const.{value}'.format(value=name)
if not name.isupper():
raise self.ConstCaseError, 'Const's name is not all uppercase'
self.__dict__[name] = value
#使用
ConstValue.GOOGLE = 100
如上,如果你在对GOOGLE赋值之后再去修改它的值,就会引发一个ConstError。而如果你的常量名不是全部大写,则会引发一个ConstCaseError。
接下来简单解释一下,首先在常量类中定义了两个异常类型,用于在发生异常时阻止非法操作并提供恰当的异常信息以供调试。接下来重写了这个类的描述符中的__setter__来进行赋值时阻止非法操作,并把已有的常量名存在类字典(__dict__)中。