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

  1. 常量的各个字母使用大写字母表示,中间以下划线连接:如 MAX_VALUE;
  2. 常量的值一旦绑定则不可以再修改。

由于常量的值一旦绑定则不可再修改,所以也就是说对常量二次赋值时需要抛出异常。因此我们显然需要改写自定义的常量类的赋值方法。在 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 定义自己的常量类的更多相关文章

  1. Python 定义常量

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

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

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

  3. python定义接口继承类

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

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

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

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

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

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

    转自:  http://cowboy.1988.blog.163.com/blog/static/75105798201091141521583/ 1.关于定义类的一些奇特之处  今天在Python中 ...

  7. Python 中的函数与类的方法

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

  8. python学习小结4:类

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

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

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

随机推荐

  1. 零元学Expression Blend 4 – Chapter 20 以实作案例学习Childwindow

    原文:零元学Expression Blend 4 – Chapter 20 以实作案例学习Childwindow 本章将教大家如何运用Blend 4内建的假视窗原件-「ChildWindow」 Chi ...

  2. 零元学Expression Blend 4 - Chapter 1 缘起

    原文:零元学Expression Blend 4 - Chapter 1 缘起 本来都使用Adobe相关工具从事设计工作的我,因缘际会下,接触到了Expression Blend 4,让我完全的对微软 ...

  3. RedHat 7.3+ORACLE 12c RAC 使用udev绑定磁盘

    在RedHat 7中,很多命令发生了改变,其中使用udev对磁盘绑定的命令也发生了变更,不再使用start_udev,而是改为了udevadm,下面具体介绍如何使用udev对磁盘进行绑定,这里对6和7 ...

  4. java基础之super关键字

    一.在java里面,对于super关键字通常有两种用法: 1. 用在子类的构造方法里(初始化用),主要是调用父类的默认构造方法,如果父类有不止一个构造方法,可以通过super指定具体的构造函数,比如 ...

  5. 如何在 Xcode 中进行 Qt 开发(可使用使用 Homebrew 来安装qt)

    第一步 安装 Qt 分为两种情况: 1. 希望使用 Qt Quick 等先进Qt5技术, 2. 只需要 Qt 4.8的类库即可. 第一种, 直接去官网下载 Mac安装包, 在此不作过多说明, 开发时也 ...

  6. 朱晔的互联网架构实践心得S2E6:浅谈高并发架构设计的16招

    朱晔的互联网架构实践心得S2E6:浅谈高并发架构设计的16招 概览 标题中的高并发架构设计是指设计一套比较合适的架构来应对请求.并发量很大的系统,使系统的稳定性.响应时间符合预期并且能在极端的情况下自 ...

  7. Delphi中,indy控件实现收发邮件的几点学习记录( 可以考虑加入多线程,用多个邮箱做一个邮箱群发器) 转

    关于用Delphi中的Indy控件实现收发邮件的几点学习记录             这几天心里颇不宁静,不是因为项目延期,而是因为自己几个月前做的邮件发送程序至今无任何进展,虽然一向谦虚的人在网上发 ...

  8. 学习Java,容易被你忽略的小细节(3)

    在<学习Java,容易被你忽略的小细节(2)>中我们已经深入讨论过String类中equals()方法的使用,在本文中我们将进一步讨论equals()方法在其他境况下的使用方法. 首先,我 ...

  9. ansible(二)

    一.软件相关模块 1.yum(下载包) 正常操作 yum 与rpm的区别 yum可以解决依赖关系rpm 全称readhat package manager(红帽包管理工具),需要自己解决依赖 yum源 ...

  10. 面试官:你了解过Redis对象底层实现吗

    上一章我们讲了Redis的底层数据结构,不了解的人可能会有疑问:这个和平时用的五大对象有啥关系呢?这一章我们就主要解释他们所建立的联系. 看这个文件之前,如果对ziplist.skiplist.int ...