课时46:魔法方法:描述符(property的原理)
目录:
一、描述符(property的原理)
二、课时46课后习题及答案
**********************************
一、描述符(property的原理)
**********************************
本节要讲的内容叫作描述符,用一句话解释,描述符就是将某种特殊类型的类的实例指派给另一个类的属性。那什么是特殊类型的类呢?就是至少要在这个类里边定义__get__()、__set__()或__delete__()三个特殊方法中的任意一个。
下表列举了描述符相关的魔法方法:
__get__(self, instance, owner) 用于访问属性,它返回属性的值
__set__(self, instance, value) 将在属性分配操作中调用,不返回任何内容
__delete__(self, instance) 控制删除操作,不返回任何内容
举个直观的例子:
class MyDescriptor:
def __get__(self, instance, owner):
print("getting...", self, instance, owner) def __set__(self, instance, value):
print("setting...", self, instance, value) def __delete__(self, instance):
print("deleting...", self, instance) class Test:
x = MyDescriptor()
由于MyDescriptor实现了__get__()、__set__()和__delete__()方法,并且将它的类实例指派给Test类的属性,所以MyDescriptor就是所谓描述符类。到这里,大家有没有看到property()的影子?
好,实例化Test类,然后尝试着对x属性进行各种操作,看看描述符类会有怎样的响应:
>>> test = Test()
>>> test.x
getting... <__main__.MyDescriptor object at 0x000001559C681CF8> <__main__.Test object at 0x000001559C67A588> <class '__main__.Test'>
当访问x属性的时候,Python会自动调用描述符的__get__()方法,几个参数的内容分别是:self是描述符类自身的实例;instance是这个描述符的拥有者所在的类的实例,在这里也就是Test类的实例;owner是这个描述符的拥有者所在的类本身。
>>> test.x = 'X-man'
setting... <__main__.MyDescriptor object at 0x000001559C681CF8> <__main__.Test object at 0x000001559C67A588> X-man
对x属性进行赋值操作的时候,Python会自动调用__set__()方法,前两个参数跟__get__()方法是一样的,最后一个参数value是等号右边的值。
最后一个del操作也是同样的道理:
>>> del test.x
deleting... <__main__.MyDescriptor object at 0x000001559C681CF8> <__main__.Test object at 0x000001559C67A588>
只要弄清楚描述符,那么property的秘密就不再是秘密了!property事实上就是一个描述符类。下边就定义一个属于我们自己的MyProperty:
class MyProperty:
def __init__(self, fget=None, fset=None, fdel=None):
self.fget = fget
self.fset = fset
self.fdel = fdel def __get__(self, instance, owner):
return self.fget(instance) def __set__(self, instance, value):
self.fset(instance, value) def __delete__(self, instance):
self.fdel(instance) class C:
def __init__(self):
self._x = None def getX(self):
return self._x def setX(self, value):
self._x = value def delX(self):
del self._x x = MyProperty(getX, setX, delX)
>>> c = C()
>>> c.x = 'X-man'
>>> c.x
'X-man'
>>> c._x
'X-man'
>>> del c.x
>>> c.x
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
c.x
File "C:\Users\14158\Desktop\MyProperty.py", line 8, in __get__
return self.fget(instance)
File "C:\Users\14158\Desktop\MyProperty.py", line 21, in getX
return self._x
AttributeError: 'C' object has no attribute '_x'
看,这不就实现了property()函数了嘛,简单吧?!
最后讲一个实例:
先定义一个温度类,然后定义两个描述符类用于描述摄氏度和华氏度两个属性。
要求两个属性会自动进行转换,也就是说你可以给摄氏度这个属性赋值,然后打印的华氏度属性是自动转换后的结果。
class Celsius:
def __init__(self, value = 26.0):
self.value = float(value) def __get__(self, instance, owner):
return self.value def __set__(self, instance, value):
self.value = float(value) class Fahrenheit:
def __get__(self, instance, owner):
return instance.cel * 1.8 + 32 def __set__(self, instance, value):
instance.cel = (float(value) - 32) / 1.8 class Temperature:
cel = Celsius()
fah = Fahrenheit()
>>> temp = Temperature()
>>> temp.cel
26.0
>>> temp.fah
78.80000000000001
*******************************
二、课时46课后习题及答案
*******************************
课时46:魔法方法:描述符(property的原理)的更多相关文章
- NDK开发之获得域和方法描述符
在NDK开发之调用方法和NDK开发之访问域两篇博客中,我们在获得域ID和方法ID时都需要一个叫做描述符的参数,那么在实际开发中我们怎么知道我们要调用的域或者方法的描述符呢? 一个简单的方法就是使用Ja ...
- 11.python描述符---类的装饰器---@property
描述符1.描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()这三个内置方法中的一个,描述符也被称为描述符协议(1):__ ...
- python - 数据描述符(class 内置 get/set/delete方法 )
数据描述符(class 内置 get/set/del方法 ): # 什么是描述符 # 官方的定义:描述符是一种具有“捆绑行为”的对象属性.访问(获取.设置和删除)它的属性时,实际是调用特殊的方法(_g ...
- property 和 魔法方法
property和魔法方法 一.property 二.model,class,bases,mro 三.__doc__, __dict__,__call__,__item__,__len__,__str ...
- 【python】描述符descriptor
开始看官方文档,各种看不懂,只看到一句Properties, bound and unbound methods, static methods, and class methods are all ...
- Python——描述符(descriptor)解密
本文由 极客范 - 慕容老匹夫 翻译自 Chris Beaumont.欢迎加入极客翻译小组,同我们一道翻译与分享.转载请参见文章末尾处的要求. Python中包含了许多内建的语言特性,它们使得代码简洁 ...
- python2.7高级编程 笔记二(Python中的描述符)
Python中包含了许多内建的语言特性,它们使得代码简洁且易于理解.这些特性包括列表/集合/字典推导式,属性(property).以及装饰器(decorator).对于大部分特性来说,这些" ...
- Python描述符(descriptor)解密(转)
原文:http://www.geekfan.net/7862/ Python中包含了许多内建的语言特性,它们使得代码简洁且易于理解.这些特性包括列表/集合/字典推导式,属性(property).以及装 ...
- Python 描述符 (descriptor)
1.什么是描述符? 描述符是Python新式类的关键点之一,它为对象属性提供强大的API,你可以认为描述符是表示对象属性的一个代理.当需要属性时,可根据你遇到的情况,通过描述符进行访问他(摘自Pyth ...
- Python笔记(4)类__属性与描述符
部分参考自:http://www.geekfan.net/7862/ 新式类与经典类 2和3不一样,3都是新式类. 新式类和经典类的区别: class A: #classic class " ...
随机推荐
- 【转】你是不是也被Android Private Libraries、Referenced Libraries、android Dependency搞晕了~~
一.v4.v7.v13的作用和用法 1.Android Support V4, V7, V13是什么? 本质上就是三个java library. 2.为什么要有support库? 是为了解决软件的 ...
- 【P1330】 封锁阳光大学
两个和谐河蟹不能在同一条边的两端.所以对于每条边.只有一个节点有和谐河蟹 所以说,我们可以将有和谐河蟹的看做一种颜色,或则是状态.没有河蟹看做另一种言颜色 这样边变成了二分图染色 所以嗯~(・∀・) ...
- IE问题——列表项图像
等我们实现列表时,经常会遇到一种情况:需要为列表的每一项的前面添加一个列表项图像. 我们在查阅W3C时会发现,在CSS中已经为我们提供了实现方法——“list-style-type”,我们来看看它的实 ...
- Java关键字transient和volatile小结
转自:http://heaven-arch.iteye.com/blog/1160693 transient和volatile两个关键字一个用于对象序列化,一个用于线程同步,都是Java中比较高阶的话 ...
- 【Java】对象、类(抽象类与内部类)、接口
博文内容概况 对象和类 抽象类 接口 内部类 对象和类 对象是对客观事物的抽象,类是对对象的抽象.类是一种数据类型,其外观和行为由用户定义.类中可以设置两种类型的元素:字段(有时被称为数据成员)和方法 ...
- 关于 export default 和 export
// 第一组 export default function crc32() { // 输出 // ... } import crc32 from 'crc32'; // 输入 // 第二组 expo ...
- ES6初识-解构赋值
数组解构赋值 [a,b]=[1,2]; . 方法返回 function f(){ return [1,2] } let a,b; [a,b]=f();//a=1,b=2 function f1() ...
- 01U盘PE系统制作方法
1. 需要的工具和安装包:WinPE镜像文件 WinPE_x86.iso .已制作好的另一个启动盘(下文以映像总裁为例,当然也可以使用大白菜.U启动等) . 电脑.准备制作PE系统的空U盘 2. 还原 ...
- java.lang.UnsupportedOperationException 原因以及解决方案
如下代码: Map[] cardProds = JsonUtils.getObject(oldCartValue, new TypeReference<Map[]>(){}); List& ...
- 生产者消费者-Java代码实现
import java.util.LinkedList; class Storage{ private static final int MAX = 100; LinkedList<Object ...