目录:

  一、描述符(property的原理)

  二、课时46课后习题及答案

**********************************

一、描述符(property的原理)

**********************************

本节要讲的内容叫作描述符,用一句话解释,描述符就是将某种特殊类型的类的实例指派给另一个类的属性。那什么是特殊类型的类呢?就是至少要在这个类里边定义__get__()、__set__()或__delete__()三个特殊方法中的任意一个。

下表列举了描述符相关的魔法方法:

  1. __get__(self, instance, owner) 用于访问属性,它返回属性的值
  2. __set__(self, instance, value) 将在属性分配操作中调用,不返回任何内容
  3. __delete__(self, instance) 控制删除操作,不返回任何内容

举个直观的例子:

  1. class MyDescriptor:
  2. def __get__(self, instance, owner):
  3. print("getting...", self, instance, owner)
  4.  
  5. def __set__(self, instance, value):
  6. print("setting...", self, instance, value)
  7.  
  8. def __delete__(self, instance):
  9. print("deleting...", self, instance)
  10.  
  11. class Test:
  12. x = MyDescriptor()

由于MyDescriptor实现了__get__()、__set__()和__delete__()方法,并且将它的类实例指派给Test类的属性,所以MyDescriptor就是所谓描述符类。到这里,大家有没有看到property()的影子?

好,实例化Test类,然后尝试着对x属性进行各种操作,看看描述符类会有怎样的响应:

  1. >>> test = Test()
  2. >>> test.x
  3. getting... <__main__.MyDescriptor object at 0x000001559C681CF8> <__main__.Test object at 0x000001559C67A588> <class '__main__.Test'>

当访问x属性的时候,Python会自动调用描述符的__get__()方法,几个参数的内容分别是:self是描述符类自身的实例;instance是这个描述符的拥有者所在的类的实例,在这里也就是Test类的实例;owner是这个描述符的拥有者所在的类本身。

  1. >>> test.x = 'X-man'
  2. setting... <__main__.MyDescriptor object at 0x000001559C681CF8> <__main__.Test object at 0x000001559C67A588> X-man

对x属性进行赋值操作的时候,Python会自动调用__set__()方法,前两个参数跟__get__()方法是一样的,最后一个参数value是等号右边的值。

最后一个del操作也是同样的道理:

  1. >>> del test.x
  2. deleting... <__main__.MyDescriptor object at 0x000001559C681CF8> <__main__.Test object at 0x000001559C67A588>

只要弄清楚描述符,那么property的秘密就不再是秘密了!property事实上就是一个描述符类。下边就定义一个属于我们自己的MyProperty:

  1. class MyProperty:
  2. def __init__(self, fget=None, fset=None, fdel=None):
  3. self.fget = fget
  4. self.fset = fset
  5. self.fdel = fdel
  6.  
  7. def __get__(self, instance, owner):
  8. return self.fget(instance)
  9.  
  10. def __set__(self, instance, value):
  11. self.fset(instance, value)
  12.  
  13. def __delete__(self, instance):
  14. self.fdel(instance)
  15.  
  16. class C:
  17. def __init__(self):
  18. self._x = None
  19.  
  20. def getX(self):
  21. return self._x
  22.  
  23. def setX(self, value):
  24. self._x = value
  25.  
  26. def delX(self):
  27. del self._x
  28.  
  29. x = MyProperty(getX, setX, delX)
  1. >>> c = C()
  2. >>> c.x = 'X-man'
  3. >>> c.x
  4. 'X-man'
  5. >>> c._x
  6. 'X-man'
  7. >>> del c.x
  8. >>> c.x
  9. Traceback (most recent call last):
  10. File "<pyshell#5>", line 1, in <module>
  11. c.x
  12. File "C:\Users\14158\Desktop\MyProperty.py", line 8, in __get__
  13. return self.fget(instance)
  14. File "C:\Users\14158\Desktop\MyProperty.py", line 21, in getX
  15. return self._x
  16. AttributeError: 'C' object has no attribute '_x'

看,这不就实现了property()函数了嘛,简单吧?!

最后讲一个实例:

  1. 先定义一个温度类,然后定义两个描述符类用于描述摄氏度和华氏度两个属性。
  2. 要求两个属性会自动进行转换,也就是说你可以给摄氏度这个属性赋值,然后打印的华氏度属性是自动转换后的结果。
  1. class Celsius:
  2. def __init__(self, value = 26.0):
  3. self.value = float(value)
  4.  
  5. def __get__(self, instance, owner):
  6. return self.value
  7.  
  8. def __set__(self, instance, value):
  9. self.value = float(value)
  10.  
  11. class Fahrenheit:
  12. def __get__(self, instance, owner):
  13. return instance.cel * 1.8 + 32
  14.  
  15. def __set__(self, instance, value):
  16. instance.cel = (float(value) - 32) / 1.8
  17.  
  18. class Temperature:
  19. cel = Celsius()
  20. fah = Fahrenheit()
  1. >>> temp = Temperature()
  2. >>> temp.cel
  3. 26.0
  4. >>> temp.fah
  5. 78.80000000000001

*******************************

二、课时46课后习题及答案

*******************************

课时46:魔法方法:描述符(property的原理)的更多相关文章

  1. NDK开发之获得域和方法描述符

    在NDK开发之调用方法和NDK开发之访问域两篇博客中,我们在获得域ID和方法ID时都需要一个叫做描述符的参数,那么在实际开发中我们怎么知道我们要调用的域或者方法的描述符呢? 一个简单的方法就是使用Ja ...

  2. 11.python描述符---类的装饰器---@property

    描述符1.描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()这三个内置方法中的一个,描述符也被称为描述符协议(1):__ ...

  3. python - 数据描述符(class 内置 get/set/delete方法 )

    数据描述符(class 内置 get/set/del方法 ): # 什么是描述符 # 官方的定义:描述符是一种具有“捆绑行为”的对象属性.访问(获取.设置和删除)它的属性时,实际是调用特殊的方法(_g ...

  4. property 和 魔法方法

    property和魔法方法 一.property 二.model,class,bases,mro 三.__doc__, __dict__,__call__,__item__,__len__,__str ...

  5. 【python】描述符descriptor

    开始看官方文档,各种看不懂,只看到一句Properties, bound and unbound methods, static methods, and class methods are all ...

  6. Python——描述符(descriptor)解密

    本文由 极客范 - 慕容老匹夫 翻译自 Chris Beaumont.欢迎加入极客翻译小组,同我们一道翻译与分享.转载请参见文章末尾处的要求. Python中包含了许多内建的语言特性,它们使得代码简洁 ...

  7. python2.7高级编程 笔记二(Python中的描述符)

    Python中包含了许多内建的语言特性,它们使得代码简洁且易于理解.这些特性包括列表/集合/字典推导式,属性(property).以及装饰器(decorator).对于大部分特性来说,这些" ...

  8. Python描述符(descriptor)解密(转)

    原文:http://www.geekfan.net/7862/ Python中包含了许多内建的语言特性,它们使得代码简洁且易于理解.这些特性包括列表/集合/字典推导式,属性(property).以及装 ...

  9. Python 描述符 (descriptor)

    1.什么是描述符? 描述符是Python新式类的关键点之一,它为对象属性提供强大的API,你可以认为描述符是表示对象属性的一个代理.当需要属性时,可根据你遇到的情况,通过描述符进行访问他(摘自Pyth ...

  10. Python笔记(4)类__属性与描述符

    部分参考自:http://www.geekfan.net/7862/ 新式类与经典类 2和3不一样,3都是新式类. 新式类和经典类的区别: class A: #classic class " ...

随机推荐

  1. 旧文备份:rtlinux安装手册

    前段时间接触了几天RTLinux,折腾了好几天才总算把它安装上,得益于Prof. Chang-Gun Lee的安装建议,觉得该文档可能会对准备尝试安装RTLinux的朋友们有帮助,本人英语很烂,也比较 ...

  2. CTS、CLS、CLR分别作何解释?

    CTS.CLS.CLR分别作何解释? 答:CTS:通用类型系统.CLS:通用语言规范.CLR:公共语言运行库.

  3. element el-tooltip 内容换行的方法

    <el-tooltip class="item" effect="light" placement="top-start">  ...

  4. mac安装mysql及workbench

    安装mysql 登录MySQL网站 打开网站Download MySQL Community Server,选择下方的dmg文件下载 点击download,此处为8.0.11版本 然后选择no tha ...

  5. mysql中列属性

    mysql列属性包括:NULL .default.comment.primary key.unique key 一.NULL定义方式:NULL(默认) NOT NULL 空属性有2个值,mysql数据 ...

  6. Java执行存储过程

    1.JDBC调用存储过程: CallableStatement /** *p是要调用的存储过程的名字,存储过程的4个参数,用4个?号占位符代替 *其余地方写法固定 */ CallableStateme ...

  7. thinkphp5,单图,多图,上传

    /** * 上传单图 */ function upload($path, $filename) { $file = request()->file($filename); $info = $fi ...

  8. MPP(大规模并行处理)

    1. 什么是MPP? MPP (Massively Parallel Processing),即大规模并行处理,在数据库非共享集群中,每个节点都有独立的磁盘存储系统和内存系统,业务数据根据数据库模型和 ...

  9. const用法总结(通俗易懂)

    const的意思可以概括为 “一个不能被改变的普通变量” ,使得const在一定程度上提高程序的安全性和可靠性. const的几种情况: 1. const的普通用法 int const size: c ...

  10. Python学习笔记:单例模式

    单例模式:一个类无论实例化多少次,返回的都是同一个实例,例如:a1=A(), a2=A(), a3=A(),a1.a2和a3其实都是同一个对象,即print(a1 is a2)和print(a2 is ...