因为种种原因,Python并未提供如C/C++/Java一样的const修饰符,换言之,python中没有常量,至少截止2015年年末,还没有这个打算。Python程序一般通过约定俗成的变量名全大写的形式来表示这是一个常量,但是这终究不是长久之计。

其实Python可以曲线救国实现常量。

在Python的面向对象中,

object.__setattr__()

这个built-in function在对类的属性赋值的时候会自动调用。其函数原型为:

object.__setattr__(self, name, value)

其中name为变量名,value为变量值。

而object.__dict__则以dict的形式保存了object内所有可写的属性,key为变量名,value为变量值。

那么我们就有可能通过建立一个const类,对其object.__setattr__()方法进行overwrite,在对属性值进行赋值的时候判断,如果属性存在,则表示这是对常量的重赋值操作,从而抛出异常,如果属性不存在,则表示是新声明了一个常量,可以进行赋值操作。

const.py 代码如下:

# -*- coding: utf-8 -*-

class _const:
class ConstError(TypeError) : pass def __setattr__(self, key, value):
# self.__dict__
if self.__dict__.has_key(key):
raise self.ConstError,"constant reassignment error!"
self.__dict__[key] = value import sys sys.modules[__name__] = _const()

其中,1-10行是上述思路的类的一个实现。

第12-14行的写法值得说明。我们尽管拥有了_const类,但是我们当前使用这个类仍然需要

import const

c = const._const()
c.TEST_CONSTANT = 'test'

这样的形式来声明一个常量TEST_CONSTANT,然而我们希望用更简洁的方法进行常量的赋值。形如:

import const

const.TEST_CONSTANT = 'test'

在python中,__name__内置属性是当前的class或者type的值。通俗地讲,__name__的值有以下两种形式:

      • 如果运行某一个py文件,在该文件中,__name__的值为'__main__'
      • 如果import了某一个py文件,那么在该import的文件中,__name__的值为该文件的文件名(不带.py后缀)

而sys.modules是一个dict对象,包括了当前上下文中python已经load的所有模块的信息,dict的key为文件名,value为模块对象。

在const.py
中,14行的写法等价于

import const

sys.modules['const'] = _const()

即,让_const类作为模块的入口点,引入const.py等价于声明了一个_const类的实例。

至此python的常量实现完毕,使用test.py测试:

# -*- coding: utf-8 -*-

import const

const.TEST = 'test'
print const.TEST
const.TEST1 = 'test1'
print const.TEST1
const.TEST = 'test'
print const.TEST

打印信息如下:

test
test1
Traceback (most recent call last):
File "H:/code/test.py", line 9, in <module>
const.TEST = 'test'
File "H:\code\const.py", line 9, in __setattr__
raise self.ConstError,"constant reassigning error!"
const.ConstError: constant reassignment error!

  

成功为两常量赋值,在试图修改第一个常量值时抛出异常:)

python实现不可修改的常量的更多相关文章

  1. Python中的变量和常量

    本文主要介绍Python中的变量和常量,包括变量的命名规范,使用注意事项 -------------- 完美的分割线 --------------- 1.变量 1.1.变量理解 1)什么是变量 变量即 ...

  2. 简述Python垃圾回收机制和常量池的验证

    目录 通过代码验证python解释器内部使用了常量池 Python的引入 变量的引入 为什么要有变量 定义变量 常量引入 常量池引入 Python解释器 Python变量存储机制 Python垃圾回收 ...

  3. Python基础部分:5、 python语法之变量与常量

    目录 python语法之变量与常量 一.什么是变量与常量 1.什么是变量 2.什么是常量 二.变量的基本使用 1.代码中如何记录事物状态 2.变量使用的语法结构与底层原理 3.变量名的命名规范 4.变 ...

  4. Python默认版本修改

    Python默认版本修改 当电脑安装了多个版本的Python,而Shell中默认的Python不是你想要的,这个时候就需要对Python的默认版本进行修改. 在Windows中,可以通过修改环境变量的 ...

  5. python 基础之注释变量常量

    一:注释 注释: 就是对代码的解释 方便大家阅读代码 1.注释的分类 (1)单行注释 #  在python中在行首添加一个#号就将这一行进行注释 #单行注释: 用#开头,后面跟上任意字符串 #pyth ...

  6. 孤荷凌寒自学python第五十三天使用python写入和修改Firebase数据库中记录

     孤荷凌寒自学python第五十三天使用python写入和修改Firebase数据库中记录 (完整学习过程屏幕记录视频地址在文末) 今天继续研究Firebase数据库,利用google免费提供的这个数 ...

  7. python requests接收chunked编码问题-python源码修改

    python requests接收chunked编码问题-python源码修改 学习了:https://blog.csdn.net/wangzuxi/article/details/40377467

  8. Python的字符串修改报错:TypeError: 'str' object does not support item assignment

    Python中想修改字符串的最后一个字符,使用name[-1] = 'e'来实现,运行后报错. 报错内容是:TypeError: 'str' object does not support item ...

  9. python禁止函数修改列表的实现方法

    python禁止函数修改列表的实现方法 有时候,需要禁止函数修改列表.例如要对裂变进行修改操作,也要保留原来的未打印的设计列表,以供备案.为解决这个问题,可向函数传递列表的副本而不是原件:这样函数所做 ...

随机推荐

  1. 【Cocosd2d实例教程二】地图编辑器Tiled的安装使用

    (转载请注明出处:http://blog.csdn.net/buptgshengod) 我们知道cocos2d是一个基于2d效果的游戏引擎,那么如果制作一个2d手机游戏我们需要创建相应的游戏画面,而c ...

  2. Hibernate下的Many-to-Many的级联删除

    hibernate下的Many-to-Many的级联删除 Hibernate多对多的例子不少,但仔细一看,大多数都是保存的,删除谈的少,但问题还不少,因此有必须简单测试一下,以下我们来个简单的多对多关 ...

  3. ubuntu装机后的一些零散配置

    -2 以root用户登录 su passwd root 可参考http://blog.csdn.net/happyteafriends/article/details/7518893 : 先设定一个r ...

  4. ThinkPad L421 如何禁用触摸板

    控制面板 - 硬件和声音 - 鼠标 . 选中如下图所示的 UltraNav 选项卡. 将 启用 TouchPad 前的 √ 去掉即可. 如果没有 UltraNav 这一选项卡,可至联想官网下载相关驱动 ...

  5. ubuntu下root用户配置

    01 接着,输入su root,以root用户登录, 由于命令提示符太长,这里输入export PS1='[\u@\h \W]$'重新设置了一下提示符,然后输入 cp -p /etc/lightdm/ ...

  6. 21.allegro下鼠标形状设置[原创]

    1. -- --- ----- ---

  7. [Golang]使用自建代理访问指定网站

    由于爬虫过于频繁访问某一个网站而被禁ip,只因为贪恋一时爽快而忘记了使用代理,这大概是大多数爬虫初学者遇到的问题吧.但是有一些网站不只是爬虫需要访问,人也是需要访问的.这时候就需要使用代理服务器来访问 ...

  8. Codeforces Beta Round #97 (Div. 1)

    B 判矩阵的时候 出了点错 根据点积判垂直 叉积判平行 面积不能为0 #include <iostream> #include<cstdio> #include<cstr ...

  9. Android在OnCreate中获取控件的宽度和高度

    在Android中,有时需要对控件进行测量,得到的控件宽度和高度可以用来做一些计算.在需要自适应屏幕的情况下,这种计算就显得特别重要.另一方便,由于需求的原因,希望一进入界面后,就能得到控件的宽度和高 ...

  10. 【笨嘴拙舌WINDOWS】GDI对象之位图

    GDI对象在windows中可以描述成为一次绘画操作时可使用的抽象工具.包括(画笔.画刷.字体.区域.调色板.位图等) GDI对象里的对象概念和在编程领域中面向对象编程的对象概念是不一样的! GDI对 ...