目录

1. 描述符基础

2. 描述符方法

2.1 方法简述

__get__(self, instance, owner):

__set__(self, instance, value):

__delete__(self, instance):

2.2 方法参数

2.3 简单示例

3. 操作实例


1. 描述符基础

描述符(descriptor),就是将某种特殊类型的类的实例对象,赋另一个类的属性;

描述符方法,包括 __get__、__set__、__delete__ 三种魔法方法,只有当定义它们的一个类(descriptor类)的实例对象被赋给另一个类(owner类)的类属性时使用;

前文所学习的 property() 函数,实际上就是一个包含了三种描述符方法的描述符类;

注意描述符的实例对象,需要赋给类属性,访问实例层次上的描述符只会返回描述符本身,无法自动调用 __get__ 和 __set__ 方法。

#创建描述符类
class TestDescriptor:def __init__(self, nameinfo):self.nameinfo = nameinfodef __get__(self, instance, owner):return self.nameinfo#创建将描述符类实例对象赋给实例属性的类
class TestOwner:def __init__(self, nameinfo2):self.nameinfo2 = nameinfo2self.x = TestDescriptor(self.nameinfo2)#调用由描述符类赋值的实例属性,不能正确调用魔法方法
testx = TestOwner('test')
testx.x
<__main__.TestDescriptor object at 0x00000238691615B0>
testx.x.__dict__
{'nameinfo': 'test'}
testx.x.nameinfo
'test'#创建将描述符类实例对象赋给类属性的类
class TestOwner2:nameinfo2 = 'test'x = TestDescriptor(nameinfo2)#调用由描述符类赋值的类属性,正确调用魔法方法
testy = TestOwner2()
testy.y
'test'

2. 描述符方法

2.1 方法简述

__get__(self, instance, owner):

获取 owner 类或 owner 的实例(instance)属性,返回属性的值;

__set__(self, instance, value):

设置 owner类的一个实例对象(instance)的属性为新的 value,没有返回值;

__delete__(self, instance):

删除 owner类的一个实例对象(instance)的属性,没有返回值;

2.2 方法参数

描述符方法的各个参数说明:

  • self:descriptor类,即描述符类的实例对象;
  • instance:owner类的实例对象
  • owner:owner类
  • value:用于设置属性的值

2.3 简单示例

如下示例,简单表现描述符类的使用,以及描述符方法各个参数实际调用对象:

#创建 descriptor 类,展示各个参数
class TestDescriptor:def __get__(self, instance, owner):print(f'__get__方法各参数值为,self:{self},instance:{instance},owner:{owner}')def __set__(self, instance, value):print(f'__set__方法各参数值为,self:{self},instance:{instance},value:{value}')def __delete__(self, instance):print(f'__delete__方法各参数值为,self:{self},instance:{instance}')#创建 Owner 类,Owner 类中创建 descriptor 类的实例作为 Owner 类的一个属性
class TestOwner:ins_D = TestDescriptor()#创建 Owner 类的实例
ins_O = TestOwner()#Owner 类和类的实例对象
ins_O
<__main__.TestOwner object at 0x0000024E5B4E4F40>
TestOwner
<class '__main__.TestOwner'>#对 Owner 类中属性,也即 descriptor 类的实例作设置,调用 descriptor 类的 __set__ 方法
class TestOwner:
ins_O.ins_D = 'Testinfo: value'
__set__方法各参数值为,self:<__main__.TestDescriptor object at 0x0000024E5B4A2670>,instance:<__main__.TestOwner object at 0x0000024E5B4E4F40>,value:Testinfo: value#对 Owner 类中属性,也即 descriptor 类的实例作读取,调用 descriptor 类的 __get__ 方法
ins_O.ins_D
__get__方法各参数值为,self:<__main__.TestDescriptor object at 0x0000024E5B4A2670>,instance:<__main__.TestOwner object at 0x0000024E5B4E4F40>,owner:<class '__main__.TestOwner'>#对 Owner 类中属性,也即 descriptor 类的实例作删除,调用 descriptor 类的 __delete__ 方法
del ins_O.ins_D
__delete__方法各参数值为,self:<__main__.TestDescriptor object at 0x0000024E5B4A2670>,instance:<__main__.TestOwner object at 0x0000024E5B4E4F40>

3. 操作实例

property 函数自行实现实操:

#通过描述符类实现的类似 property 函数的 TestProperty 类
class TestProperty:def __init__(self, getdef, setdef, deldef):self.getdef = getdefself.setdef = setdefself.deldef = deldefdef __get__(self, instance, owner):return self.getdef(instance)def __set__(self, instance, value):self.setdef(instance,value)def __delete__(self, instance):self.deldef(instance)#调用描述符类:TestProperty,实现类似 property 函数效果
class TestOwner:def __init__(self, info = 'testinfo'):self.info = infodef getinfo(self):return self.infodef setinfo(self, newinfo):self.info = newinfodef delinfo(self):del self.infoins_D = TestProperty(getinfo, setinfo, delinfo)#创建 TestOwner 的实例对象
ins_O = TestOwner()#调用实例对象 ins_O 属性 ins_D,也即 TestProperty 的实例对象
#获取 ins_O.ins_D 属性
ins_O.ins_D
'testinfo'
#设置 ins_O.ins_D 属性,并查询
ins_O.ins_D = 'Hello, World!'
ins_O.ins_D
'Hello, World!'
#删除 ins_O.ins_D 属性,并验证删除成功
del ins_O.ins_D
ins_O.ins_D
Traceback (most recent call last):File "<input>", line 1, in <module>File "<input>", line 8, in __get__File "<input>", line 21, in getinfo
AttributeError: 'TestOwner' object has no attribute 'info'

温度类实操,要求如下:

  • 定义一个温度类,然后定义两个描述符类用于描述摄氏度和华氏度两个属性;
  • 要求两个属性会自动转换,即可以给摄氏度属性赋值,获取华氏度则自动转换刚才赋值的摄氏度;
#创建摄氏度描述符类
class Celsius:def __init__(self, value=0.0):self.value = float(f'{value:.2f}')def __get__(self, instance, owner):return self.valuedef __set__(self, instance, value):self.value = float(f'{value:.2f}')#创建华氏度描述符类
class Fahrenheit:def __get__(self, instance, owner):return (instance.cel * 1.8) + 32def __set__(self, instance, value):tempcel = (float(value) - 32) / 1.8instance.cel = float(f'{tempcel:.2f}')#创建温度类
class Temperature:cel = Celsius()fah = Fahrenheit()#创建温度类的实例
tempx = Temperature()#通过温度类的实例,对类属性 cel/fah 做读取、设置,调用魔法方法成功
tempx.cel
0.0
tempx.cel = 25
tempx.cel
25.0
tempx.fah
77.0
tempx.fah = 100
tempx.cel
37.78

类和对象11:描述符方法相关推荐

  1. python描述符魔术方法_学习笔记-Python基础9-面向对象编程OOP-类的成员描述符(property)、类的常用内置属性、类的常用魔术方法、类和对象的三种方法...

    一.类的成员描述符(property) 类的成员描述符是为了在类中,对类的成员属性进行相关操作而创建的一种方式,大部分属于数据清洗 属性有三种操作:get获取属性值.set修改或添加属性.delete ...

  2. python 描述符类_python的黑魔法--描述符

    python的黑魔法 描述符 官方定义:python描述符是一个"绑定行为"的对象属性,在描述符协议中,它可以通过方法重写属性的访问.这些方法有 get(), set(), 和de ...

  3. [C# 类和对象]-C# 中的方法以及类和对象编程

    ################################################## 目录 C# 的方法 C# 定义方法 访问修饰符 返回值类型 方法名 参数列表 方法主体 方法名的命 ...

  4. 高阶Day1:面向对象,面向过程,类和对象的属性和方法创建

    高阶Day1:面向对象,面向过程,类和对象的属性和方法创建 高级编程学习4个内容: 面向对象 MySQL数据库 网络编程 并发编程 面向过程(POP)与面向对象(OOP): 类和对象: 类名的定义: ...

  5. 【译文】 C#面向对象的基本概念 (Basic C# OOP Concept) 第一部分(类,对象,变量,方法,访问修饰符)...

    译文出处:http://www.codeproject.com/Articles/838365/Basic-Csharp-OOP-Concept 相关文档:http://files.cnblogs.c ...

  6. java类描述_java笔记2:Java语言中的类和对象的描述

    在Java 语言中,除8 个基本数据类型值之外, 一切都是对象,而对象就是面向对象程序设计的中心. 对象是人们要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,它不仅能表示具体的事物,还 ...

  7. JAVA类和对象(构造方法、方法重载、this关键字)

    Java是一门完全面向对象的编程语言:类和对象是面向对象编程的基础和核心. 面向对象的编程思想是来源于现实生活:面向对象编程是使用代码来模拟现实生活中的场景. 1.现实生活中有哪些是对象? 对象:在现 ...

  8. 类 Class 对象、定义、方法

    面向对象的定义 类 Class: 用来描述具体相同的属性和方法的对象的集合.定义了该集合中每个对象所共有的属性和方法.对象是类的示例. 类变量:类变量在整个实例化的对象中是公用的.类变量定义在类中且在 ...

  9. 类和对象,属性和方法

    1. 定义 类:把某一类事物的属性提取出来,形成类,类有属性(也叫成员变量/field字段)和行为 对象:一个具体的实例 注意:从类到对象的说法:1)创建一个对象2)实例化一个对象3)把类实例化 成员 ...

  10. Python面向对象——面向对象介绍、实现面向对象编程、定义类、再调用类产生对象、总结__init__方法、查找顺序

    文章目录 面向对象介绍 实现面向对象编程 一:先定义类 二:再调用类产生对象 总结__init__方法 查找顺序 面向对象介绍 ''' 面向过程:核心是"过程"二字过程的终极奥义就 ...

最新文章

  1. 安徽全国计算机缴费,全国计算机等级考试3月报名 安徽首次网上报名缴费
  2. win7完美兼容DynamipsGUI(小凡模拟器)攻略
  3. 解决Adobe Reader安装错误150120
  4. 【qduoj - 夏季学期创新题】最长公共子串(水题暴力枚举,不是LCS啊)
  5. java水文模型,分布式水文模型.ppt
  6. 整理加解释:以太网、快速以太网、千兆以太网和万兆以太网分别的概念和区分 大详解
  7. 2021年中国电子签名行业研究报告
  8. 7.2图的存储结构(邻接矩阵)
  9. Splunk学习心得
  10. mysql拉数据到本地_从mysql中dump数据到本地
  11. mysql 还原 批量ibd_MySQL只有.frm和.ibd文件如何批量恢复InnoDB表-爱可生
  12. java实现微信公众平台中的字典排序
  13. 拦截器 参数不过去 的解决方法
  14. mysql配置好后_安装完 MySQL 后必须调整的 10 项配置
  15. day01--课后练习
  16. html5svg在线编辑器,HTML5 SVG简介
  17. 图书租赁管理系统 图书馆借书还书 计算机毕设项目
  18. linux表白程序源码,程序员表白程序,开放源码在此!
  19. android 背景渐变颜色代码,Android开发——实现背景颜色渐变效果
  20. 基本知识 100190

热门文章

  1. 自动化测试(定位元素的方式,浏览器操作)
  2. 财务上的大写数字从1到10分别是?
  3. c# 财务报表数字转大写的方法
  4. kafka offset 机制
  5. ERROR: Pool overlaps with other one on this address space 解决办法
  6. analogWrite怎么做PWM输出?改PWM频率(定时器相关)
  7. OkHttp缓存与连接
  8. 目标检测一阶段和二阶段对比图
  9. Spring框架基础(中)
  10. Spring-IOC与AOP是解决什么问题的?