在實際的程序開發中,咱們一般會將一個不可變的變量聲明爲一個常量。在不少高級語言中都會提供常量的關鍵字來定義常量,如 C++
中的 const
, Java
中的 final
等,可是 Python
語言由於變量無類型,因此也就不存在這樣的修飾符,其自己並未提供任何機制來進行常量的定義。所以咱們只能經過本身定義類的方法來定義一個符合常量規則的類,使得該類定義的成員屬性知足常量的屬性。常量通常符合如下兩條規則:html
- 常量的各個字母使用大寫字母表示,中間如下劃線鏈接:如
MAX_VALUE
;- 常量的值一旦綁定則不能夠再修改。
因爲常量的值一旦綁定則不可再修改,因此也就是說對常量二次賦值時須要拋出異常。所以咱們顯然須要改寫自定義的常量類的賦值方法。在 Python
中,當咱們對類的屬性進行賦值時,會自動調用 object
類的 __setattr__()
函數,該函數的定義以下:python
object.__setattr__(self, name, value)
其中的 name
表示屬性的名稱,value
是試圖賦值給 name
的值,其中 object
類的 object.__dict__
以字典的形式保存了全部已賦值的屬性。函數
所以咱們能夠經過定義一個常量類 constant
類(默認繼承自object
),並對 object.__setattr__()
方法進行重寫。因爲常量有兩條規則,因此咱們須要根據這兩條規則自定義兩個異常處理,分別是二次賦值的異常處理和名稱非大寫的異常處理。code
異常處理的定義方式請參看:Python 錯誤和異常orm
constant.pyhtm
import sys class _const: # 自定義異常處理 class ConstError(PermissionError): pass class ConstCaseError(ConstError): pass # 重寫 __setattr__() 方法 def __setattr__(self, name, value): if name in self.__dict__: # 已包含該常量,不能二次賦值 raise self.ConstError("Can't change const {0}".format(name)) if not name.isupper(): # 全部的字母須要大寫 raise self.ConstCaseError("const name {0} is not all uppercase".format(name)) self.__dict__[name] = value # 將系統加載的模塊列表中的 constant 替換爲 _const() 實例 sys.modules[__name__] = _const()
在其它文件中定義常量,test.py繼承
import constant constant.VALUE = 5 constant.VALUE = 4 # ConstError constant.vaLue = 1 # ConstCaseError
當咱們識圖修改常量 VALUE
的值或者定義一個名稱不是所有大寫的常量時,都會拋出異常,這樣就達到了不可更改常量的值的目的。開發