Python 定义只读属性的实现方式

作者:Daniel2333 时间:2023-04-28 01:11:22 

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

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

通过私有属性

Python里定义私有属性的方法见 https://www.jb51.net/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

来源:https://blog.csdn.net/weixin_35653315/article/details/78077253

标签:Python,定义,只读属性
0
投稿

猜你喜欢

  • Burpsuite模块之Burpsuite Intruder模块详解

    2023-11-24 05:31:24
  • 解析MySQL join查询的原理

    2024-01-17 13:28:46
  • 利用ThinkPHP内置的ThinkAjax实现异步传输技术的实现方法

    2023-09-11 15:11:50
  • Python pip安装lxml出错的问题解决办法

    2021-11-17 07:36:07
  • python基础之while循环语句的使用

    2021-03-16 16:54:20
  • ASP生成XML文件

    2009-06-29 16:28:00
  • 部署ASP.NET Core程序到Windows系统

    2024-05-09 09:04:38
  • ASP设计常见问题及解答精要

    2009-04-21 11:16:00
  • flask设置cookie

    2022-03-19 21:13:01
  • ASP正则获取图片地址

    2009-09-03 13:18:00
  • JavaScript队列的应用实例详解【经典数据结构】

    2024-04-16 09:53:13
  • Python3中函数参数传递方式实例详解

    2022-05-22 23:32:20
  • 浅谈MySQL触发器的原理以及使用

    2024-01-19 02:44:46
  • 使用C#连接并读取MongoDB数据库

    2024-01-15 17:12:13
  • Pandas实现数据拼接的操作方法详解

    2023-08-16 02:45:40
  • python3的pip路径在哪

    2023-01-27 14:15:39
  • python新手学习使用库

    2021-06-20 13:08:38
  • 基于进程内通讯的python聊天室实现方法

    2021-01-24 03:50:53
  • python实现滑雪游戏

    2021-10-08 05:20:35
  • python 实现数组list 添加、修改、删除的方法

    2021-10-21 16:27:34
  • asp之家 网络编程 m.aspxhome.com