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函数定义与实例变量同名的属性会怎样?> 但如果 ...
随机推荐
- Allegro16.6和17.0和17.2中将板框导出DXF文件
Allegro16.6和17.0和17.2中将板框导出DXF文件 转载 https://blog.csdn.net/pieces_thinking/article/details/69817600 标 ...
- 算法排序-lowB三人组
冒泡排序思路: 选择排序思路: 插入排序思路: 小结: 详细代码解释看下一篇
- ubuntu 16.04 更新 gcc/g++ 4.9.2
ubuntu 转载 2016年10月12日 :: 标签:ubuntu /g++ /gcc [html] view plain copy sudo dpkg -l g++ 最近在学C++primer , ...
- 【SVN版本回退】
[SVN版本回退]根据想要回退的内容,然后选择revert to this revision或者revert changes from this revision.下面引用过来:譬如有个文件,有十个版 ...
- iframe仿ajax图片上传
1.前台页面: iframe_upload.html <html> <body> <form action="upload.php" id=" ...
- Python 008- 游戏2048
#-*- coding:utf-8 -*- import curses from random import randrange, choice # generate and place new ti ...
- MapReduce源代码分析之LocatedFileStatusFetcher
LocatedFileStatusFetcher是MapReduce中一个针对给定输入路径数组,使用配置的线程数目来获取数据块位置的有用类. 它的主要作用就是利用多线程技术.每一个线程相应一个任务.每 ...
- No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=x86_64, VALID_ARCHS=i386).错误解决方法
targets ->build setting 下的 Build Active Architecture Only 设置 NO 就可以.
- appium导入哪些java模块
简单介绍 讲解一个appium测试脚本需要导入哪些java模块. 导入的java模块 明确两点信息: 一个脚本需要讲清楚测试环境:1.自动化平台方面,测试的平台是什么(appium或者selendro ...
- delphi如何让程序最小化到任务栏(使用Shell_NotifyIcon API函数)
现在很多的应用程序都有这样一种功能,当用户选择最小化窗口时,窗口不是象平常那样最小化到任务栏上,而是“最小化”成一个任务栏图标.象FoxMail 3.0 NetVampire 3.0等都提供了这样的功 ...