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

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

通过私有属性

用私有属性+@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
1

PS:遇到问题没人解答?需要Python学习资料?可以加点击下方链接自行获取

note.youdao.com/noteshare?id=2dce86d0c2588ae7c0a88bee34324d76

所以呢, 只需要在__ 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 ONL

Python中定义只读属性的更多相关文章

  1. python中定义函数和参数的传递问题

    作者:達聞西链接:https://zhuanlan.zhihu.com/p/24162430来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 5.2.4 函数.生成器和类 ...

  2. Python中什么是变量Python中定义字符串

    在Python中,变量的概念基本上和初中代数的方程变量是一致的. 例如,对于方程式 y=x*x ,x就是变量.当x=2时,计算结果是,当x=5时,计算结果是25. 只是在计算机程序中,变量不仅可以是数 ...

  3. 在python中定义二维数组

    发表于 http://liamchzh.0fees.net/?p=234&i=1 一次偶然的机会,发现python中list非常有意思. 先看一段代码 [py]array = [0, 0, 0 ...

  4. 在Python中定义和使用抽象类的方法

    https://www.jb51.net/article/87710.htm 像java一样python也可以定义一个抽象类. 在讲抽象类之前,先说下抽象方法的实现. 抽象方法是基类中定义的方法,但却 ...

  5. Python 如何定义只读属性?【新手必学】

    前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:Daniel2333如果还没学到属性问题,看不懂不怪你,可以先去小编的P ...

  6. Python中定义文档字符串__doc__需要注意格式对齐的处理

    Python中的文档字符串是个很不错的提升代码交付质量.编写文档方便的特征,但是需要注意在使用文档字符串时,将文档字符串标识的引号对必须遵守缩进的规则,否则Python语法检查时会无法通过,而引号内的 ...

  7. python中定义的颜色

    平时学习工作中,我们经常会接触到一些大佬写的Python实用工具,运行起来总会显示出五颜六色的背景,相关的定义在matplotlib模块中,为方便使用,这里给大家展示一下在这个模块中都定义了哪些选颜色 ...

  8. Python中定义字符串

    字符串可以用''或者""括起来表示.如果字符串本身包含'怎么办?比如我们要表示字符串 I'm OK ,这时,可以用" "括起来表示: "I'm OK& ...

  9. Python中定义函数时参数有默认值的小陷阱

    在定义函数的时候,如果函数的参数有默认值,有两种类型的参数,一种是整数,字符串这种不可变类型,另一种是列表这种可变类型,对于第一种情况没有什么特殊的地方,但是对于可变类型,有一个微妙的小陷阱. 可变类 ...

随机推荐

  1. UML类图绘制

    UML图简介 含义:UML-Unified Modeling Language 统一建模语言,又称标准建模语言.是用来对软件密集系统进行可视化建模的一种语言 主要模型: 功能模型:从用户的角度展示系统 ...

  2. 【开发者portal在线开发插件系列四】数组 及 可变长度数组

    基础篇 基础场景见上面两个帖子,这里单独说明数组和可变长度数组的用法. 话不多说,开始今天的演(表)示(演) Profile和插件开发 添加一个string类型的属性: 在插件里添加一条数据上报消息: ...

  3. NumPy 学习 第三篇:矢量化和广播

    矢量化 矢量化是指用数组表达式替换显式的for循环.在Python中循环数组或其他跟数组类似的数据结构时,使用循环会涉及很多开销.NumPy中的矢量化操作把内部循环委托给高度优化的C和Fortran函 ...

  4. Sql Server连表查询字段为null

    这是一个坑,并且是有毒的坑. 一不小心我就掉进了这个坑里面,费了好大的力气这才从坑里面爬出来. 话不多说,开始吹BB啦. 一.简单说说遇到的问题: 连表查询,一对多. 出现 int,  smallda ...

  5. luogu P2812 校园网络【[USACO]Network of Schools加强版】|Tarjan

    题目背景 浙江省的几所OI强校的神犇发明了一种人工智能,可以AC任何题目,所以他们决定建立一个网络来共享这个软件.但是由于他们脑力劳动过多导致全身无力身体被♂掏♂空,他们来找你帮助他们. 题目描述 共 ...

  6. iOS 网络基本剖析

    一.网络通信的本质 数据传输,数据交换 Client     <======>  服务器 二.HTTP.TCP,IP.UDP.Socket关系刨析 Socket:套接字,是一个用于网络传输 ...

  7. mac端口占用

    lsof -i tcp:port 可以查看该端口被什么程序占用,并显示PID port 替换成端口号, eg: lsof -i tcp:8081 kill pid 杀死PID

  8. Spring Boot Validation,既有注解不满足,我是怎么暴力扩展validation注解的

    前言 昨天,我开发的代码,又收获了一个bug,说是界面上列表查询时,正常情况下,可以根据某个关键字keyword模糊查询,后台会去数据库 %keyword%查询(非互联网项目,没有使用es,只能这样了 ...

  9. Mybatis的模糊查询以及自动映射

    Mybatis的模糊查询 1.  参数中直接加入%% ? 1 2 3 4 5 6 7 8 9 param.setUsername("%CD%");       param.setP ...

  10. PyCharm配置Gitee

    PyCharm配置Gitee 第一步:下载安装Git https://git-scm.com/download/win 第二步:打开PyCharm,配置Git File->Setting-> ...