在实际的程序开发中,我们通常会将一个不可变的变量声明为一个常量。在很多高级语言中都会提供常量的关键字来定义常量,如 C++ 中的 const , Java 中的 final 等,但是 Python 语言因为变量无类型,所以也就不存在这样的修饰符,其本身并未提供任何机制来进行常量的定义。因此我们只能通过自己定义类的方法来定义一个符合常量规则的类,使得该类定义的成员属性满足常量的属性。常量一般符合以下两条规则:

常量的各个字母使用大写字母表示,中间以下划线连接:如 MAX_VALUE;

常量的值一旦绑定则不可以再修改。

由于常量的值一旦绑定则不可再修改,所以也就是说对常量二次赋值时需要抛出异常。因此我们显然需要改写自定义的常量类的赋值方法。在 Python 中,当我们对类的属性进行赋值时,会自动调用 object 类的 __setattr__() 函数,该函数的定义如下:

object.__setattr__(self, name, value)

其中的 name 表示属性的名称,value 是试图赋值给 name 的值,其中 object 类的 object.__dict__ 以字典的形式保存了所有已赋值的属性。

因此我们可以通过定义一个常量类 constant 类(默认继承自object),并对 object.__setattr__() 方法进行重写。由于常量有两条规则,所以我们需要根据这两条规则自定义两个异常处理,分别是二次赋值的异常处理和名称非大写的异常处理。

异常处理的定义方式请参看:Python 错误和异常

定义常量类:

constant.py
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 的值或者定义一个名称不是全部大写的常量时,都会抛出异常,这样就达到了不可更改常量的值的目的。

Python 定义常量

常量在编写程序的时候,一旦设定就不能再进行变动,常量一种约定俗成的方式,所有字母大写并用下划线分隔单词的方式(如MAX_VALUE, OUT_TIME等),但是python没有提供设置常量用法,需要自 ...

python的异常处理及异常类定义

python的异常处理语法和大多数语言相似: try: try块的语句... except exceptiontype1 as var:#使用as语句获得本次捕获到的异常的实例var except块语 ...

python定义接口继承类

zxq547 python定义接口继承类invalid syntax解决办法 1 2 3 4 5 6 7 class s_all(metaclass=abc.ABCMeta):     #python ...

Python语法基础-函数,类以及调试处理

[TOC] 1. 函数的定义 python中函数有两种: python自带的函数 用户定义函数 返回多个值 原来返回值是一个tuple!但是,在语法上,返回一个tuple可以省略括号,而多个变量可以同 ...

python基础——实例属性和类属性

python基础——实例属性和类属性 由于Python是动态语言,根据类创建的实例可以任意绑定属性. 给实例绑定属性的方法是通过实例变量,或者通过self变量: class Student(objec ...

python 静态方法,类方法 ,类的继承

1.关于定义类的一些奇特之处  今天在Python中 ...

Python 中的函数与类的方法

注:本文转译自 Stackoverflow 上 Adding a Method to an Existing Object 的最佳回答. 在 python 中,def 定义的函数与类中的方法有很大的不 ...

python学习小结4:类

虽然Python是解释性语言,但是它是面向对象的,能够进行对象编程. 类和对象是面向对象编程的两个主要方面.类:创建一个新类型,而对象是这个类的实例,类使用class关键字创建.类的域和方法被列在一个 ...

Python属性、方法和类管理系列之----属性初探

在学习dict的时候,肯定听过dict是Python中最重要的数据类型,但是不一定知道为什么.马上你就会明白原因了. Python中从模块.到函数.到类.到元类,其实主要管理方法就是靠一个一个的字典. ...