Python深入浅出property特性属性
导语
在Java中,通常在类中定义的成员变量为私有变量,在类的实例中不能直接通过对象.属性直接操作,而是要通过getter和setter来操作私有变量。
而在Python中,因为有property这个概念,所以不需要写getter和setter一堆重复的代码来操作私有变量。Python“私有变量”通常在变量前加上“_”或者“__”,例如_attr或者__attr,这是约定俗成的规范。
把私有属性变成只读特性
class MyClass:
def __init__(self, x):
self._x = x
这里定义了一个MyClass类,它有一个实例变量_x,绑定了用户传来的x值。_x是私有变量,通过obj._x获取私有变量不符合语言规范,进而我们要使_x变成property(特性),通过obj.x直接访问。
改造后的代码如下:
class MyClass:
def __init__(self, x):
self._x = x
@property
def x(self):
return self._x
>>> obj = MyClass(10)
>>> obj.x
10
我们把_x变成了property特性,以只读的方式获取x的值。
我们现在想为x赋值该怎样做呢?
>>> obj.x = 999
Traceback (most recent call last):
File "xxx", line 14, in <module>
obj.x = 23
AttributeError: can't set attribute
可以看到,抛出了AttributeError: can't set attribute。显然,只读方法不支持赋值。
把私有变量变成可赋值的特性
我们只需要在上述代码改造成:
class MyClass:
def __init__(self, x):
self._x = x
@property
def x(self):
return self._x
@x.setter
def x(self, value):
self._x = value
>>> obj = MyClass(10)
>>> obj.x = 999
>>> obj.x
999
可以看到,我们为x添加了setter,可以直接为obj.x赋值操作
property属性能够遮盖实例属性
继续上面的代码,我们看看以下的操作:
>>> obj = MyClass(10)
>>> obj.__dict__
{'_x': 999} #此时实例变量中有_x的值
>>> obj.__dict__['x'] = 99999 #设置obj的实例变量有x值,跟property属性重名!
>>> obj.__dict__
{'_x': 999, 'x': 99999} #此时实例变量中有_x和x的值
>>> obj.x #结果是obj的实例变量还是property属性?
10
如上代码所示,obj对象有一个_x实例变量和一个x的property属性,我们又强行为obj增加了一个x实例变量,这个实例变量x和property属性x同名!
通过obj.x我们得知,返回的是property属性,说明property属性会遮盖实例属性!也可以理解为property属性的优先级更大!
property类解析
我们通常使用内置的@property装饰器。但其实property是一个类,python中类和函数的调用方式都差不多,他们都是可调用对象
property的构造方法如下:
class property(object):
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
""""""
它最大接受4个参数,都可以为空。
第一个为getter,第二个为setter,第三个为delete函数,第四个为文档。
上述代码的另一种写法
class MyClass:
def __init__(self, x):
self._x = x
def get_x(self):
return self._x
def set_x(self, value):
self._x = value
x = property(get_x, set_x)
>>> obj = MyClass(10)
>>> obj.x
10
如上,x是property的实例,设置了getter和setter,作为类变量放在MyClass类中。
以上就是property属性的解析。
Python深入浅出property特性属性的更多相关文章
- python 使用@property 操作属性时,报“RecursionError:maximun recursion depth exceeded”
使用@property获取和修改属性,出现报错"RecursionError:maximun recursion depth exceeded",超过了最大的递归深度 原因: 方法 ...
- python的property属性
最近看书中关于Python的property()内建函数属性内容时<python核心编程>解释的生僻难懂,但在网上看到了一篇关于property属性非常好的译文介绍. http://pyt ...
- Property - 特性(Python)
Property - Python 特性 不同的书籍对 property 一词的翻译有所不同, 我们将 property 翻译成 '特性' 以区别于 attribute 一词. 先看看 propert ...
- python对象属性管理(2):property管理属性
使用Property管理属性 python提供了一种友好的getter.setter.deleter类方法的属性管理工具:property. property()是一个内置函数,它返回一个Proper ...
- python 中 property 属性的讲解及应用
Python中property属性的功能是:property属性内部进行一系列的逻辑计算,最终将计算结果返回 property属性的有两种方式: 1. 装饰器 即:在方法上应用装饰器 2. 类属性 即 ...
- 【转】python之property属性
1. 什么是property属性 一种用起来像是使用的实例属性一样的特殊属性,可以对应于某个方法 # ############### 定义 ############### class Foo: def ...
- python中property属性的介绍及其应用
Python的property属性的功能是:property属性内部进行一系列的逻辑计算,最终将计算结果返回. 使用property修饰的实例方法被调用时,可以把它当做实例属性一样 property的 ...
- 第7.23节 Python使用property函数定义属性简化属性访问的代码实现
第7.23节 Python使用property函数定义属性简化属性访问的代码实现 一. 背景 在本章前面章节中,我们介绍了类相关的知识,并举例进行了说明,在这些例子中会定义一些形如 ...
- Python使用property函数定义的属性名与其他实例变量重名会怎么样?
首先如果定义的属性名与该属性对应的操作方法操作的实例对象同名就会触发无穷的递归调用,相关部分请参考<Python案例详解:使用property函数定义与实例变量同名的属性会怎样?> 但如果 ...
随机推荐
- Android开源git40个App源代码
(JamsMusicPlayer)非常棒的音乐播放器(new) (F8)日程安排的软件 (Conversations)基于XMPP的应用 (Bitocle)能够在手机上查看自己github ...
- 系统安全-Firewall
Netfilter/iptables是与最新的2.6.x版本Linux内核集成的ip信息包过滤系统.如果Linux系统连接到因特网或LAN.服务器或连接LAN和因特网的代理服务器,则该系统有理由在Li ...
- vue-导入静态文件
vue导入静态文件不用像网上说的那么麻烦,其实跟普通Django项目导入类似,vue项目中有一个static文件,将你的静态文件放入到里面,然后引入就好 导入的时候和普通Django程序类似:↓ &l ...
- PHP框架的基本原理以及选择标准
PHP框架的原理 说到PHP框架,可能很多PHP新手会感到有些胆怯.其实,PHP框架也不是那么深不可测的,框架就是别人使用PHP基础只是为你写好了的东西,只是封装在一起:这就好比我们使用PHP的函数, ...
- 两个经典的文件IO程序示例
前言 本文分析两个经典的C++文件IO程序,提炼出其中文件IO的基本套路,留待日后查阅. 程序功能 程序一打印用户指定的所有文本文件,程序二向用户指定的所有文本文件中写入数据. 程序一代码及其注释 # ...
- VC ++6.0英文版常用菜单使用参考【转载整理】
(1)File菜单 New:打开“new”对话框,以便创建新的文件.工程或工作区. Close Workspace:关闭与工作区相关的所有窗口. Exit:退出VC6环境,将提示保存窗口内容等. (2 ...
- 继续聊WPF——获取ComboBox中绑定的值
千万不要认为WPF中的数据绑定会很复杂,尽管它的确比Winform程序灵活多了,但其本质是不变的,特别是ComboBox控件,我们知道在Winform中对该控件的有两个专为数据绑定而设定的属性——Di ...
- java四种线程池简介,使用
为什么使用线程池 1.减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务. 2.可以根据系统的承受能力,调整线程池中工作线线程的数目,防止消耗过多的内存 3.web项目应该创建统 ...
- 九度OJ 1097:取中值 (中值)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:5092 解决:1411 题目描述: 存在两组数组,和4个数字a,b,c,d,要求做如下操作,将第一个数组第a个数到第b个数,第二个数组的第c ...
- mongodb学习之:条件操作符
在前面的章节中我们已经有用到了条件操作符,这里我们再重点介绍下.MongoDB中条件操作符有: (>) 大于 - $gt (<) 小于 - $lt (>=) 大于等于 - $gte ...