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中的默认参数详解
Jun 24 Python
Python多进程分块读取超大文件的方法
Apr 13 Python
对Pandas DataFrame缺失值的查找与填充示例讲解
Nov 06 Python
python 实现一次性在文件中写入多行的方法
Jan 28 Python
PyQt5 在label显示的图片中绘制矩形的方法
Jun 17 Python
python过滤中英文标点符号的实例代码
Jul 15 Python
简单了解Django应用app及分布式路由
Jul 24 Python
Python面向对象原理与基础语法详解
Jan 02 Python
通过实例解析Python return运行原理
Mar 04 Python
基于python检查SSL证书到期情况代码实例
Apr 04 Python
Python爬虫抓取论坛关键字过程解析
Oct 19 Python
python 读取串口数据的示例
Nov 09 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-MySQL教程归纳总结
2008/06/07 PHP
php上传文件,创建递归目录的实例代码
2013/10/18 PHP
php 使用GD库为页面增加水印示例代码
2014/03/24 PHP
laravel 5.1下php artisan migrate的使用注意事项总结
2017/06/07 PHP
php写入文件不覆盖的实例讲解
2019/09/17 PHP
PHP7 弃用功能
2021/03/09 PHP
JavaScript-世界上误解最深的语言分析
2007/08/12 Javascript
基于JQuery的一个简单的鼠标跟随提示效果
2010/09/23 Javascript
六款帮助你实现惊艳视差滚动效果的jQuery插件
2012/09/14 Javascript
js中直接声明一个对象的方法
2014/08/10 Javascript
javascript正则表达式之search()用法实例
2015/01/19 Javascript
JavaScript变量的作用域全解析
2015/08/14 Javascript
vue实现点击展开点击收起效果
2018/04/27 Javascript
vue axios数据请求及vue中使用axios的方法
2018/09/10 Javascript
vue自定义tap指令及tap事件的实现
2018/09/18 Javascript
VUE2.0+ElementUI2.0表格el-table实现表头扩展el-tooltip
2018/11/30 Javascript
Node.js console控制台简单用法分析
2019/01/04 Javascript
JS实现的新闻列表自动滚动效果示例
2019/01/30 Javascript
深入解析koa之中间件流程控制
2019/06/17 Javascript
JS实现电商商品展示放大镜特效
2020/01/07 Javascript
如何使用gpu.js改善JavaScript的性能
2020/12/01 Javascript
Python中的高级数据结构详解
2015/03/27 Python
Python类的动态修改的实例方法
2017/03/24 Python
python实现冒泡排序算法的两种方法
2018/03/10 Python
Python实现爬取马云的微博功能示例
2019/02/16 Python
Django 中自定义 Admin 样式与功能的实现方法
2019/07/04 Python
python给list排序的简单方法
2020/12/10 Python
python通过cython加密代码
2020/12/11 Python
Python爬取梨视频的示例
2021/01/29 Python
为什么使用接口?
2014/08/13 面试题
新颖的化妆品活动方案
2014/08/21 职场文书
村党支部群众路线教育实践活动对照检查材料
2014/09/26 职场文书
2014年教务处工作总结
2014/12/03 职场文书
销售工作决心书
2015/02/04 职场文书
事业单位财务人员岗位职责
2015/04/14 职场文书
python turtle绘图
2022/05/04 Python