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入门指引
Apr 01 Python
Python标准库defaultdict模块使用示例
Apr 28 Python
Python计算两个日期相差天数的方法示例
May 23 Python
Python lambda函数基本用法实例分析
Mar 16 Python
Python math库 ln(x)运算的实现及原理
Jul 17 Python
Django的Modelforms用法简介
Jul 27 Python
python获取指定日期范围内的每一天,每个月,每季度的方法
Aug 08 Python
Python3显示当前时间、计算时间差及时间加减法示例代码
Sep 07 Python
pygame实现五子棋游戏
Oct 29 Python
浅谈Python中文件夹和python package包的区别
Jun 01 Python
Django之腾讯云短信的实现
Jun 12 Python
4种方法python批量修改替换列表中元素
Apr 07 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
虫族 Zerg 热键控制
2020/03/14 星际争霸
php文件上传的两种实现方法
2016/04/04 PHP
PHP 将数组打乱 shuffle函数的用法及简单实例
2016/06/17 PHP
php使用ftp远程上传文件类(完美解决主从文件同步问题的方法)
2016/09/23 PHP
PHP设计模式之装饰器(装饰者)模式(Decorator)入门与应用详解
2019/12/13 PHP
js中有关IE版本检测
2012/01/04 Javascript
jquery动态添加删除一行数据示例
2014/06/12 Javascript
原生js封装二级城市下拉列表的实现代码
2016/06/16 Javascript
微信小程序 火车票查询实例讲解
2016/10/17 Javascript
jQuery扩展+xml实现表单验证功能的方法
2016/12/25 Javascript
微信小程序实现图片预加载组件
2017/01/18 Javascript
详解Vue-Cli 异步加载数据的一些注意点
2017/08/12 Javascript
JS动画定时器知识总结
2018/03/23 Javascript
vue-swiper的使用教程
2018/08/30 Javascript
优雅的elementUI table单元格可编辑实现方法详解
2018/12/23 Javascript
重学 JS:为啥 await 不能用在 forEach 中详解
2019/04/15 Javascript
vue实现手机端省市区区域选择
2019/09/27 Javascript
jquery 遍历hash操作示例【基于ajax交互】
2019/10/12 jQuery
vue各种事件监听实例(小结)
2020/06/24 Javascript
在Python中使用正则表达式的方法
2015/08/13 Python
padas 生成excel 增加sheet表的实例
2018/12/11 Python
python对列进行平移变换的方法(shift)
2019/01/10 Python
对django views中 request, response的常用操作详解
2019/07/17 Python
Python代码注释规范代码实例解析
2020/08/14 Python
英国排名第一的冲浪店:Ann’s Cottage
2020/06/21 全球购物
介绍下WebSphere的安全性
2013/01/31 面试题
车间班长岗位职责
2013/11/30 职场文书
工商治理实习生的自我评价分享
2014/02/20 职场文书
公司党的群众路线教育实践活动领导班子对照检查材料
2014/09/25 职场文书
学生实习证明模板汇总
2014/09/25 职场文书
工会积极分子个人总结
2015/03/03 职场文书
学生犯错保证书
2015/05/09 职场文书
小马王观后感
2015/06/11 职场文书
贷款工作证明模板
2015/06/12 职场文书
家长对孩子的寒假评语
2015/10/09 职场文书
承诺书怎么写 ?
2019/04/16 职场文书