Python 定义只读属性的实现方式


Posted in Python onMarch 05, 2020

Python是面向对象(OOP)的语言, 而且在OOP这条路上比Java走得更彻底, 因为在Python里, 一切皆对象, 包括int, float等基本数据类型.

在Java里, 若要为一个类定义只读的属性, 只需要将目标属性用private修饰, 然后只提供getter()而不提供setter(). 但Python没有private关键字, 如何定义只读属性呢? 有两种方法, 第一种跟Java类似, 通过定义私有属性实现. 第二种是通过__setattr__.

通过私有属性

Python里定义私有属性的方法见 https://3water.com/article/181953.htm.

用私有属性+@property定义只读属性, 需要预先定义好属性名, 然后实现对应的getter方法.

class Vector2D(object):
 def __init__(self, x, y):
 self.__x = float(x)
 self.__y = float(y)

 @property
 def x(self):
 return self.__x
 @property
 def y(self):
 return self.__y

if __name__ == "__main__":
 v = Vector2D(3, 4)
 print(v.x, v.y)
 v.x = 8 # error will be raised.

输出:

(3.0, 4.0)
Traceback (most recent call last):
 File ...., line 16, in <module>
 v.x = 8 # error will be raised.
AttributeError: can't set attribute

可以看出, 属性x是可读但不可写的.

通过__setattr__

当我们调用obj.attr=value时发生了什么?

很简单, 调用了obj的__setattr__方法. 可通过以下代码验证:

class MyCls():
 def __init__(self):
 pass

 def __setattr__(self, f, v):
 print 'setting %r = %r'%(f, v)
if __name__ == '__main__':
 obj = MyCls()
 obj.new_field = 1

输出:

setting 'new_field' = 1

所以呢, 只需要在__setattr__ 方法里挡一下, 就可以阻止属性值的设置, 可谓是釜底抽薪.

代码:

# encoding=utf8
class MyCls(object):
 readonly_property = 'readonly_property' 
 def __init__(self):
 pass
 def __setattr__(self, f, v):
 if f == 'readonly_property':
  raise AttributeError('{}.{} is READ ONLY'.\
     format(type(self).__name__, f))

 else:
  self.__dict__[f] = v

if __name__ == '__main__':
 obj = MyCls()

 obj.any_other_property = 'any_other_property'
 print(obj.any_other_property)

 print(obj.readonly_property)
 obj.readonly_property = 1

输出:

any_other_property
readonly_property
Traceback (most recent call last):
 File "...", line 21, in <module>
 obj.readonly_property = 1
 ...
 AttributeError: MyCls.readonly_property is READ ONLY

以上这篇Python 定义只读属性的实现方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
浅析Python中的join()方法的使用
May 19 Python
Python入门学习之字符串与比较运算符
Oct 12 Python
Python实现控制台进度条功能
Jan 04 Python
实例讲解Python中global语句下全局变量的值的修改
Jun 16 Python
centos6.7安装python2.7.11的具体方法
Jan 16 Python
python web.py开发httpserver解决跨域问题实例解析
Feb 12 Python
python构建基础的爬虫教学
Dec 23 Python
详解python中eval函数的作用
Oct 22 Python
基于python的列表list和集合set操作
Nov 24 Python
Python numpy多维数组实现原理详解
Mar 10 Python
python 实现表情识别
Nov 21 Python
关于探究python中sys.argv时遇到的问题详解
Feb 23 Python
Pycharm中import torch报错的快速解决方法
Mar 05 #Python
Python中私有属性的定义方式
Mar 05 #Python
Python实现AI自动抠图实例解析
Mar 05 #Python
python GUI库图形界面开发之PyQt5 MDI(多文档窗口)QMidArea详细使用方法与实例
Mar 05 #Python
Python matplotlib修改默认字体的操作
Mar 05 #Python
Django 返回json数据的实现示例
Mar 05 #Python
python利用opencv实现SIFT特征提取与匹配
Mar 05 #Python
You might like
php导入csv文件碰到乱码问题的解决方法
2014/02/10 PHP
PHP防范SQL注入的具体方法详解(测试通过)
2014/05/09 PHP
PHP生成树的方法
2015/07/28 PHP
js+css在交互上的应用
2010/07/18 Javascript
javascript实现可改变滚动方向的无缝滚动实例
2013/06/17 Javascript
JS动态增加删除UL节点LI及相关内容示例
2014/05/21 Javascript
javascript中if和switch,==和===详解
2015/07/30 Javascript
jquery实现带缩略图的可定制高度画廊效果(5种)
2015/08/28 Javascript
利用jQuery中的ajax分页实现代码
2016/02/25 Javascript
详解使用vue实现tab 切换操作
2017/07/03 Javascript
js 监控iframe URL的变化实例代码
2017/07/12 Javascript
浅谈react前后端同构渲染
2017/09/20 Javascript
JavaScript对象的浅拷贝与深拷贝实例分析
2018/07/25 Javascript
微信小程序之判断页面滚动方向的示例代码
2018/08/30 Javascript
js+html实现点名系统功能
2019/11/05 Javascript
用JS实现选项卡
2020/03/23 Javascript
vue滑动吸顶及锚点定位的示例代码
2020/05/10 Javascript
js里面的变量范围分享
2020/07/18 Javascript
微信小程序实现选项卡滑动切换
2020/10/22 Javascript
简单的编程0基础下Python入门指引
2015/04/01 Python
python 创建一个空dataframe 然后添加行数据的实例
2018/06/07 Python
python实现二级登陆菜单及安装过程
2019/06/21 Python
python3+opencv生成不规则黑白mask实例
2020/02/19 Python
python 实现的车牌识别项目
2021/01/25 Python
学习党章思想汇报
2014/01/07 职场文书
优秀大学生的自我评价
2014/01/16 职场文书
竞选部门副经理的自荐书范文
2014/02/11 职场文书
诉讼财产保全担保书
2014/05/20 职场文书
美术第二课堂活动总结
2014/07/08 职场文书
2014年个人教学工作总结
2014/12/09 职场文书
Django实现翻页的示例代码
2021/05/24 Python
ES6 解构赋值的原理及运用
2021/05/25 Javascript
python模块与C和C++动态库相互调用实现过程示例
2021/11/02 Python
Python实现猜拳与猜数字游戏的方法详解
2022/04/06 Python
MySQL索引 高效获取数据的数据结构
2022/05/02 MySQL
SpringBoot Http远程调用的方法
2022/08/14 Java/Android