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怎么学好python?
Oct 07 Python
Python中几个比较常见的名词解释
Jul 04 Python
完美解决Python2操作中文名文件乱码的问题
Jan 04 Python
PyQt5每天必学之弹出消息框
Apr 19 Python
python最长回文串算法
Jun 04 Python
python爬虫获取百度首页内容教学
Dec 23 Python
Pycharm 实现下一个文件引用另外一个文件的方法
Jan 17 Python
python绘制随机网络图形示例
Nov 21 Python
在OpenCV里实现条码区域识别的方法示例
Dec 04 Python
Python实现清理微信僵尸粉功能示例【基于itchat模块】
May 29 Python
Pyinstaller加密打包应用的示例代码
Jun 11 Python
Matlab中plot基本用法的具体使用
Jul 17 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类常量的使用详解
2013/06/08 PHP
PHP字符串长度计算 - strlen()函数使用介绍
2013/10/15 PHP
PHP 7安装调试工具Xdebug扩展的方法教程
2017/06/17 PHP
FireFox与IE 下js兼容触发click事件的代码
2008/11/20 Javascript
JavaScript window.setTimeout() 的详细用法
2009/11/04 Javascript
html超链接打开窗口大小的方法
2013/03/05 Javascript
jquery实现树形二级菜单实例代码
2013/11/20 Javascript
让input框实现类似百度的搜索提示(基于jquery事件监听)
2014/01/31 Javascript
jQuery实现字符串按指定长度加入特定内容的方法
2015/03/11 Javascript
基于jQuery实现的扇形定时器附源码下载
2015/10/20 Javascript
jQuery中通过ajax调用webservice传递数组参数的问题实例详解
2016/05/20 Javascript
JS代码实现根据时间变换页面背景效果
2016/06/16 Javascript
js实现多张图片延迟加载效果
2017/07/17 Javascript
vue-router实现嵌套路由的讲解
2019/01/19 Javascript
Vue实现固定定位图标滑动隐藏效果
2019/05/30 Javascript
js实现开关灯效果
2020/03/30 Javascript
vue实现前端列表多条件筛选
2020/10/26 Javascript
[02:03]《现实生活中的DOTA2》—林书豪&DOTA2职业选手出演短片
2015/08/18 DOTA
Python中的对象,方法,类,实例,函数用法分析
2015/01/15 Python
Python实现备份MySQL数据库的方法示例
2018/01/11 Python
python脚本当作Linux中的服务启动实现方法
2019/06/28 Python
python进程间通信Queue工作过程详解
2019/11/01 Python
详解Canvas 跨域脱坑实践
2018/11/07 HTML / CSS
html5移动端价格输入键盘的实现
2019/09/16 HTML / CSS
北美领先的智能产品购物网站:Wellbots
2018/06/11 全球购物
GafasWorld西班牙:购买太阳镜、眼镜和隐形眼镜
2019/09/08 全球购物
俄语翻译实习生的自我评价分享
2013/11/06 职场文书
农业资源与环境专业自荐信范文
2013/12/30 职场文书
市场营销专业求职信
2014/06/17 职场文书
求职信的正确写法
2014/07/10 职场文书
担保书格式
2015/01/20 职场文书
单位提档介绍信
2015/10/22 职场文书
2015年度学校应急管理工作总结
2015/10/22 职场文书
html+css实现环绕倒影加载特效
2021/07/07 HTML / CSS
Nginx下SSL证书安装部署步骤介绍
2021/12/06 Servers
vue+echarts实现多条折线图
2022/03/21 Vue.js