目录:

  一、描述符(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的原理)的更多相关文章

  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. G711格式语音采集/编码/转码/解码/播放

    2019-05-01 语音g711格式和AMR格式类似,应用很简单,很多人已经整理过了,收录于此,以备不时之需,用别人现成的足矣,我们的时间应该用来干更有意义的事. 1.PCM to G711 Fas ...

  2. 使用Excel管理命令输出

    效果图:(饼状图为后添加) 实现代码:

  3. weight decay 和正则化caffe

    正则化是为了防止过拟合,因为正则化能降低权重 caffe默认L2正则化 代码讲解的地址:http://alanse7en.github.io/caffedai-ma-jie-xi-4/ 重要的一个回答 ...

  4. Git学习第一天--安装Git和创建版本库

    Windows上安装Git msysgit是Windows版的Git,从https://git-for-windows.github.io下载(备份:百度网盘),然后按默认选项安装即可. 安装完成后, ...

  5. Spring Cloud 入门Eureka -Consumer服务消费(一)

    这里介绍:LoadBalancerClient接口,它是一个负载均衡客户端的抽象定义,下面我们就看看如何使用Spring Cloud提供的负载均衡器客户端接口来实现服务的消费. 引用之前的文章中构建的 ...

  6. 自定义动画函数JQuery实现

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. C#基础-hashtable,泛型和字典集合

    hashtable 的存储方式 使用方法: 1.引入包含Hashtable的命名空间 using System.Collections; // 引入Hash所在的命名空间 2.往hash表里面添加数据 ...

  8. scrapy--matplotlib

    昨天晚上看了一些关于保存文件的相关资料,早早的睡了,白天根据网上查找的资料,自己再捡起来.弄了一上午就爬取出来了,开心!!!好吧,让我们开始 老规矩,先上图.大家也赶快行动起来 分类文件: 文件内co ...

  9. centos7重启apache、nginx、mysql、php-fpm命令

    apache启动systemctl start httpd停止systemctl stop httpd重启systemctl restart httpd mysql启动systemctl start ...

  10. 开始体验第一个JAVA程序吧!

    一.准备工作(配置环境) 1.安装JAVA开发工具(JDK) a.下载符合自己电脑系统的Java开发软件:http://www.oracle.com/technetwork/java/javase/d ...