Python 定义自己的常量类
在实际的程序开发中,我们通常会将一个不可变的变量声明为一个常量。在很多高级语言中都会提供常量的关键字来定义常量,如 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 定义自己的常量类的更多相关文章
- 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 静态方法,类方法 ,类的继承
转自: http://cowboy.1988.blog.163.com/blog/static/75105798201091141521583/ 1.关于定义类的一些奇特之处 今天在Python中 ...
- Python 中的函数与类的方法
注:本文转译自 Stackoverflow 上 Adding a Method to an Existing Object 的最佳回答. 在 python 中,def 定义的函数与类中的方法有很大的不 ...
- python学习小结4:类
虽然Python是解释性语言,但是它是面向对象的,能够进行对象编程. 类和对象是面向对象编程的两个主要方面.类:创建一个新类型,而对象是这个类的实例,类使用class关键字创建.类的域和方法被列在一个 ...
- Python属性、方法和类管理系列之----属性初探
在学习dict的时候,肯定听过dict是Python中最重要的数据类型,但是不一定知道为什么.马上你就会明白原因了. Python中从模块.到函数.到类.到元类,其实主要管理方法就是靠一个一个的字典. ...
随机推荐
- System.Data.SQLite 中GUID的处理
原文:System.Data.SQLite 中GUID的处理 项目中正好用到System.Data.SQLite,在手持上使用这个数据库,因为要做数据同步,所以表中的主键都是Guid的数据类型. 在数 ...
- 读unp并动手实践
经过三个月的学习,我发现进度比较慢.照这个进度下去,平均一周花费5-6小时,还不知道读完全书需要多久. 现在做个计划,全书除开简介部分分为 基础 和 高级 套接字编程两部分,其中 基础可以分为 TCP ...
- mysql练习(一)
练习一 创建表,并插入相关数据 CREATE TABLE email ( ID INT NOT NULL PRIMARY KEY, Email VARCHAR() ) INSERT INTO emai ...
- delphi 实现微信开发(1) (使用kbmmw web server)
原文地址:delphi 实现微信开发(1)作者:红鱼儿 大体思路: 1.用户向服务号发消息,(这里可以是个菜单项,也可以是一个关键词,如:注册会员.) 2.kbmmw web server收到消息,生 ...
- 跨进程访问VCL的一个用例(Delphi6、TurboDelphi测试通过)
Controls.pas单元中有一个FindControl函数,通过句柄获得对应的TWinControl对象. function FindControl(Handle: HWnd): TWinCont ...
- Linux命令行和shell编程
Shell Shell是一个程序,用户输入的命令通过shell来传达给内核或其它程序.用户在linux打开一个终端,终端就会自动调用用户的shell. Linux上的Shell有很多种,用的最多是sh ...
- Zabbix监控ActiveMQ
当我们在线上使用了ActiveMQ 后,我们需要对一些参数进行监控,比如 消息是否有阻塞,哪个消息队列阻塞了,总的消息数是多少等等.下面我们就通过 Zabbix 结合 Python 脚本来实现对 Ac ...
- 从电子游戏到DevOps
在一个项目团队中,开发与运维之间的关系像极了知名大型游戏<刺客信条>里的故事:开发就是追求自由的刺客联盟——我喜欢用各种新颖技术手段去满足用户爸爸那些花里胡哨的需求,你别管那技术好不好用, ...
- spring 5.x 系列第22篇 —— spring 定时任务 (代码配置方式)
源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.说明 1.1 项目结构说明 关于任务的调度配置定义在ServletCo ...
- C#常用设计模式--单例模式
为什么要使用单例模式 在我们的整个游戏生命周期当中,有很多对象从始至终有且只有一个.这个唯一的实例只需要生成一次,并且直到游戏结束才需要销毁. 单例模式一般应用于管理器类,或者是一些需要持久化存在的 ...