导语

在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属性的解析。

最新文章

  1. 在 Linux 中使用 Eclipse 和 Gnu Autotools 管理 C/C++ 项目
  2. 当 jquery.unobtrusive-ajax.js 遇上Web API
  3. 详解rsync算法--如何减少同步文件时的网络传输量
  4. c# 读取嵌入式文件
  5. 【云计算】Cloudify-基于TOSCA规范的开源云应用编排系统
  6. c/c++指针总结[pointer summary]
  7. 【Sort List】cpp
  8. 每日一“酷”之string
  9. poj 3177 Redundant Paths【求最少添加多少条边可以使图变成双连通图】【缩点后求入度为1的点个数】
  10. 2.4 Git 基础 - 撤消操作
  11. is,as,sizeof,typeof,GetType
  12. iptables惹的祸
  13. 爬虫系列(1)-----python爬取猫眼电影top100榜
  14. python学习笔记(四)、条件、循环及其他语句
  15. Redis占硬盘空间
  16. C++笔记(2017/2/9)
  17. [android] 切换按钮-自定义控件
  18. SQL Server Window Function 窗体函数读书笔记一 - SQL Windowing
  19. Oracle免客户端InstantClient安装使用
  20. swift版的元组

热门文章

  1. AngularJS 实现 双击排序
  2. linux 信号屏蔽
  3. lowB三人组代码示例
  4. docker&amp;k8s填坑记
  5. node开发后将本地mysql数据导入到服务器mysql
  6. Arrays.sort(a) 自定义排序
  7. 【BZOJ2216】[Poi2011]Lightning Conductor 决策单调性
  8. curl is a tool to transfer data from or to a server curl POST
  9. java的多生产者多消费者例子
  10. UIBezierPath(转)