python类:属性
http://blog.csdn.net/pipisorry/article/details/50708616
Python 中的 property 属性
Python中有个很赞的概念,叫做property,它使得面向对象的编程更加简单。
property使用实例
假设有天你决定创建一个类,用来存储摄氏温度。当然这个类也需要实现一个将摄氏温度转换为华氏温度的方法。一种实现的方式如下:
class Celsius:
def __init__(self, temperature = 0):
self.temperature = temperature
def to_fahrenheit(self):
return (self.temperature * 1.8) + 32
我们可以用这个类产生一个对象,然后按照我们期望的方式改变该对象的温度属性:
>>> # create new object
>>> man = Celsius()
>>> # set temperature
>>> man.temperature = 37
>>> # get temperature
>>> man.temperature
>>> # get degrees Fahrenheit
>>> man.to_fahrenheit()
98.60000000000001
赋值或获取任何对象的属性
每当我们赋值或获取任何对象的属性时,例如上面展示的温度,Python都会从对象的__dict__字典中搜索它。
>>> man.__dict__
{'temperature': 37}
因此,man.temperature在其内部就变成了man.__dict__['temperature']
实例修改:建议温度不能低于-273摄氏度
现在,让我们进一步假设我们的类在客户中很受欢迎,他们开始在其程序中使用这个类。他们对该类生成的对象做了各种操作。有一天,一个受信任的客户来找我们,建议温度不能低于-273摄氏度。
使用Getters和Setters
对于上边的约束,一个很容易想到的解决方案是隐藏其温度属性(使其私有化),并且定义新的用于操作温度属性的getter和setter接口。
我们定义了两个新方法get_temperature()和set_temperature(),此外属性temperature也被替换为了_temperature。
class Celsius:
def __init__(self, temperature = 0):
self.set_temperature(temperature)
def to_fahrenheit(self):
return (self.get_temperature() * 1.8) + 32
# new update
def get_temperature(self):
return self._temperature
def set_temperature(self, value):
if value < -273:
raise ValueError("Temperature below -273 is not possible")
self._temperature = value
问题:
1. 最前边的下划线(_)用于指示Python中的私有变量。但是Python中实际上是没有私有变量的。有一些简单的被遵循的规范。Python本身不会应用任何限制。
>>> c._temperature = -300
>>> c.get_temperature()
-300
2. 先前类的客户都必须更改他们的代码
上述更新的最大问题是,所有在他们的程序中使用了我们先前类的客户都必须更改他们的代码:obj.temperature改为obj.get_temperature(),所有的赋值语句也必须更改。更新是不向后兼容地。
Property的使用
对于上边的问题,Python式的解决方式是使用property。
class Celsius:
def __init__(self, temperature = 0):
self.temperature = temperature
def to_fahrenheit(self):
return (self.temperature * 1.8) + 32
def get_temperature(self):
print("Getting value")
return self._temperature
def set_temperature(self, value):
if value < -273:
raise ValueError("Temperature below -273 is not possible")
print("Setting value")
self._temperature = value
temperature = property(get_temperature,set_temperature)
我们在get_temperature()和set_temperature()的内部增加了一个print()函数,用来清楚地观察它们是否正在执行。
代码的最后一行,创建了一个property对象temperature。简单地说,property将一些代码(get_temperature和set_temperature)附加到成员属性(temperature)的访问入口。任何获取temperature值的代码都会自动调用get_temperature(),而不是去字典表(__dict__)中进行查找。
>>> c = Celsius()
Setting value
从上边的代码中我们可以看到,即使当我们创建一个对象时,__init__()方法被调用,有一行代码self.temperature = temperature。这个任务会自动调用set_temperature()方法。
>>> c.temperature
Getting value
同样的,对于属性的任何访问,例如c.temperature,也会自动调用get_temperature()方法。
>>> c.temperature = 37
Setting value
>>> c.to_fahrenheit()
Getting value
98.60000000000001
我们可以看到,通过使用property,我们在不需要客户代码做任何修改的情况下,修改了我们的类,并实现了值约束。因此我们的实现是向后兼容的。
最后需要注意的是,实际温度值存储在私有变量_temperature中。属性temperature是一个property对象,是用来为这个私有变量提供接口的。
深入挖掘property
在Python中,property()是一个内置函数,用于创建和返回一个property对象。该函数的签名为:
property(fget=None, fset=None, fdel=None, doc=None)
这里,fget是一个获取属性值的函数,fset是一个设置属性值的函数,fdel是一个删除属性的函数,doc是一个字符串(类似于注释)。
Property对象有三个方法
getter(), setter()和delete(),用来在对象创建后设置fget,fset和fdel。
temperature = property(get_temperature,set_temperature)可以被分解为:
# make empty property
temperature = property()
# assign fget
temperature = temperature.getter(get_temperature)
# assign fset
temperature = temperature.setter(set_temperature)
它们之间是相互等价的。
作为decorator实现
熟悉Python中装饰器decorator的程序员能够认识到上述结构可以作为decorator实现。
我们可以更进一步,不去定义名字get_temperature和set_temperature,因为他们不是必须的,并且污染类的命名空间。
为此,我们在定义getter函数和setter函数时重用名字temperature。
class Celsius:
def __init__(self, temperature = 0):
self._temperature = temperature
def to_fahrenheit(self):
return (self.temperature * 1.8) + 32
@property
def temperature(self):
print("Getting value")
return self._temperature
@temperature.setter
def temperature(self, value):
if value < -273:
raise ValueError("Temperature below -273 is not possible")
print("Setting value")
self._temperature = value
上边的两种生成property的实现方式,都很简单,推荐使用。
from:http://blog.csdn.net/pipisorry/article/details/50708616
ref: python类实例计数最优方法
python类:属性的更多相关文章
- python 类属性与方法
Python 类属性与方法 标签(空格分隔): Python Python的访问限制 Python支持面向对象,其对属性的权限控制通过属性名来实现,如果一个属性有双下划线开头(__),该属性就无法被外 ...
- Python类属性访问的魔法方法
Python类属性访问的魔法方法: 1. __getattr__(self, name)- 定义当用户试图获取一个不存在的属性时的行为 2. __getattribute__(self, name)- ...
- Python类属性,实例属性
1.Python类数据属性:定义在类里面但在函数外面的变量,它们都是静态的. #一段很简单的代码,但反应了很多 >>> class A(): a=1 #一个类里面有个属性a > ...
- Python类属性详解
在python开发中,我们常常用到python的类,今天就通过实例和大家扒一扒类的属性,一起来看看吧. 类属性 1.类定义后就存在,而且不需要实例化 2.类属性使得相同类的不同实例共同持有相同变量 类 ...
- python 类属性和实例属性
class AAA(): aaa = 10 # 情形1 obj1 = AAA() obj2 = AAA() print obj1.aaa, obj2.aaa, AAA.aaa # 情形2 obj1.a ...
- python 类属性、对象属性
类的普通属性: dir(Myclass), 返回一个key列表: Myclass.__dir__,返回一个字典: 1.类的数据属性: 2.类的方法: 类的特殊属性: 1.Myclass.__name_ ...
- python类属性用法总结
属性的定义:python中的属性其实是普通方法的衍生. 操作类属性有三种方法: 1.使用@property装饰器操作类属性. 2.使用类或实例直接操作类属性(例如:obj.name,obj.age=1 ...
- python类属性和类方法(类的结构、实例属性、静态方法)
类属性和类方法 目标 类的结构 类属性和实例属性 类方法和静态方法 01. 类的结构 1.1 术语 —— 实例 使用面相对象开发,第 1 步 是设计 类 使用 类名() 创建对象,创建对象 的动作有两 ...
- python 类属性 、实例属性,可变数据结构作为类属性需要注意的地方
1.一些经典的python错误不去阅读和不重视,就会把错误的做法带入到实际项目中来,甚至造成难以排查问题. 2.有一个大笨猪,按java写观察者模式,java写得是直接在类名下声明一个实例属性(不加s ...
- 关于Python类属性与实例属性的讨论
标题名字有点长. 之所以想写这个文章是因为碰巧看到网上一篇关于Pyhon中类属性及实例属性区别的帖子.因为我之前也被这个问题困扰过,今天碰巧看到了这篇帖子,发现帖子的作者只是描述了现象,然后对原因的解 ...
随机推荐
- C++符号优先级
C++符号优先级 优先级 操作符 功能 用法 结合性 1 ()[]->.::++-- Grouping operatorArray accessMember access from a poin ...
- Linux 基本bash命令
1.查看文件大小.内存大小.cpu信息.硬盘空间 显示当前目录所有文件大小的命令:ls -lht 内存空间.CPU信息.硬盘空间:htop.top(htop详解参考:http://blog.csdn. ...
- Oracle 导入、导出DMP(备份)文件
首先说明dmp文件: Oracle备份文件是以dmp结尾,这种文件是oracle的逻辑备份文件,常用于数据库逻辑备份,数据库迁移等操作. 一.Oracle导入备份文件步骤:我用的是Oracle 11g ...
- [Luogu 1516] 青蛙的约会
Description 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事 ...
- React 关于组件(界面)更新
在最近在学 React , 将组件的UI更新稍微整理了一下.根据业务要求,可能会出现如下的技术实现要求:1.更新自己2.更新子组件3.更新兄弟组件4.更新父组件5.父 call 子 function ...
- CSS缩写的样式
熟悉和了解CSS的朋友都知道,CSS样式表有很多缩写方式.比如,定义字体.定义背景等,都可以把CSS代码缩写到一行.为了能更好的搞清楚CSS缩写方法,我收集整理了一些有关CSS简写的参考资料,也是对自 ...
- Jmeter_ForEach控制器实现网页爬虫
一直以来,爬虫似乎都是写代码去实现的,今天像大家介绍一下Jmeter如何实现一个网页爬虫! Jmeter的爬虫原理其实很简单,就是对网页提交一个请求,然后把返回的所有href提取出来,利用ForEac ...
- Mybatis 批量插入、批量更新
合理的使用批量插入.更新对性能优化有很大的作用,速度明显快了N倍. 要注意数据库连接串后面要新增:&allowMultiQueries=true,表示一个sql ...
- Docker Volume 之权限管理(一)
摘要: Volume数据卷是Docker的一个重要概念.数据卷是可供一个或多个容器使用的特殊目录,可以为容器应用存储提供有价值的特性.然而Docker数据卷的权限管理经常是非常令人困惑的.本文将结合实 ...
- app控件唯一相对Xpath自动生成(增强版uiautomatorviewer)
作者:cryanimal QQ:164166060 工具由来 前面的一篇博文较详细地介绍了uiautomatorviewer:扫描和分析Android应用程序的UI控件的工具. 熟悉控件获取的同学都知 ...