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. Hadoop原生搭建

    版本:(centos7.6) 在开始搭建平台前我已经预装了MySQL ps:MySQL创建用户并授权: grant all privileges on *.* to ' with grant opti ...

  2. CentOS下永久修改主机名

    永久修改主机名 [root@centos7 ~]# vim /etc/hostname 打开之后将原来的名字改成你想换的名字 [root@centos7 ~]# cat /etc/hostname 查 ...

  3. VIM操作记录

    =============================================== 2019/12/12_第1次修改 vr7jj ============================= ...

  4. python 金融应用(四)金融时间序列分析基础

    1.1.创建DataFrame df=pd.DataFrame(list(range(10,50,10)),columns=['num'],index=['a','b','c','d']) df Ou ...

  5. Redis中的Java分布式缓存

    为什么在分布式Java应用程序中使用缓存?今天学习了两节优锐课讲解分布式缓存的内容,收获颇多,分享给大家. 在提高应用程序的速度和性能时,每毫秒都是至关重要的.例如,根据Google的一项研究,如果网 ...

  6. Python生成器的用法

    生成器,一定情况下可以节省很多空间 比如: >>> b = (x for x in range(10)) >>> b <generator object &l ...

  7. JMeter之SteppingShape

    1.背景 其实是这样的,最近包括以前都有同事问过宝路一个问题:JMeter测试计划中涉及到梯度压测时,整个测试计划执行完毕,聚合报告看的是整体的结果啊!并不能直观看到每个梯度下的吞吐量的值(虽然可以通 ...

  8. JS基础-变量类型和类型转换

    JS 变量类型 JS中有 6 种原始值,分别是: boolean number string undefined symbol null 引用类型: 对象 数组 函数 JS中使用typeof能得到哪些 ...

  9. 【树莓派】制作启动SD卡

    版权声明:本文为博主原创文章,转载请注明出处. https://www.cnblogs.com/YaoYing/ 下载烧写软件 烧写软件 将下载的压缩文件解压缩并安装到电脑上 下载树莓派镜像 树莓派系 ...

  10. CCF-CSP题解 201803-3 URL映射

    题目要求写一个简易的URL规则和URL地址匹配的程序. 说说我的思路. 将URL规则和地址都截成片段用结构体\(<type, str[]>\)存储.对于URL规则,\(type\)为0代表 ...