Python描述符
来源:互联网 发布:淘宝店主图怎么做 编辑:程序博客网 时间:2024/05/17 02:38
看书看到了描述符,没看懂,网上找了几篇文章总结了下。
描述符是一个“绑定行为”的对象属性,在描述符协议中,可以通过方法重写属性的访问。这些方法有get(), set(), delete(),如果这些方法中的任何一个被定义在一个对象中,这个对象就是一个描述符。
Python中没有私有变量,而描述符和属性这些用来是写类似的功能。
描述符被分配给一个类,而不是实例,修改此类,会覆盖或者删除描述符本身,而不是触发它的代码。
首先看一下property类
class MathScore(): def __init__(self, std_id, score): self.std_id = std_id if score < 0: raise ValueError("Score can't be negative number!") self.__score = score def check(self): if self.__score >= 60: return 'pass' else: return 'failed' def __get_score__(self): return self.__score def __set_score__(self, value): if value < 0: raise ValueError("Score can't be negative number!") self.__score = value score = property(__get_score__, __set_score__)
此时可以直接调用score属性
xiaoming = MathScore(10, 90)xiaoming.scoreOut[30]: 90xiaoming.score = 80xiaoming.scoreOut[32]: 80xiaoming.score = -90Traceback (most recent call last): File "<ipython-input-33-aed7397ed552>", line 1, in <module> xiaoming.score = -90 File "C:/Users/xu_zh/.spyder2-py3/temp.py", line 28, in __set_score__ raise ValueError("Score can't be negative number!")ValueError: Score can't be negative number!
class property(fget=None, fset=None, fdel=None, doc=None)
工作流程:
- 实例化property实例 调用property实例会直接调用fget
- 对property实例进行赋值操作会直接调用fset,并由fset定义完成相应操作
- 删除property实例,会调用fdel删除实例
- doc是说明文档
- 如果只设置了fget,则该实例为只读对象
property还有个装饰器语法糖@property,所实现的功能与property()完全一样:
class MathScore(): def __init__(self, std_id, score): self.std_id = std_id if score < 0: raise ValueError("Score can't be negative number!") self.__score = score def check(self): if self.__score >= 60: return 'pass' else: return 'failed' @property def score(self): return self.__score @score.setter def score(self, value): #注意方法名称要与上面一致,否则会失效 if value < 0: raise ValueError("Score can't be negative number!") self.__score = value
事实上,property是基于descriptor实现的。
但是property有一个问题在于,不能复用,如果我们需要对std_id也进行检查,保证它大于0,那么还需要写一个std_id的property,这样代码就不简洁了。
这时候就需要描述符了。
The default behavior for attribute access is to get, set, or delete the attribute from an object’s dictionary. For instance, a.x has a lookup chain starting with a.dict[‘x’], then type(a).dict[‘x’], and continuing through the base classes of type(a) excluding metaclasses. If the looked-up value is an object defining one of the descriptor methods, then Python may override the default behavior and invoke the descriptor method instead. Where this occurs in the precedence chain depends on which descriptor methods were defined
用装饰符修改后的代码如下:
class Check(object): def __init__(self, name, val=None): self.name = name self.val = val def __get__(self, instance, owner): print 'Getting', self.name return self.val def __set__(self, instance, val): if val < 0: raise ValueError('Cannot be negtive') print 'Updating', self.name self.val = valclass MathScore(object): std_id = Check('std_id') score = Check('score') def __init__(self, std_id, score): self.std_id = std_id self.score = score
- Python classMethod描述符
- python描述符
- 转 python描述符
- Python 描述符
- python描述符Descriptor
- python之描述符
- 初学python描述符
- python 描述符descriptor
- python描述符详解
- Python学习---描述符
- python描述符 descriptor
- Python描述符
- python 描述符
- python 描述符类
- python 属性描述符
- python中的描述符
- python描述符和property
- 16.2 Python descriptor(描述符)
- CSS列表、表格、表单、高级选择器以及框模型
- 自定义系统右键菜单工具-使用说明
- -02-ORB算法的FPGA实现【特征点检测】
- windows 10驱动签名相关问题
- 动态规划--台阶问题
- Python描述符
- js之刷新父页面的各种方法汇总
- Ms sqlserver2008 R2大数据表的分区实现
- 获取微信用户OpenID
- Linux上如何测试、运行python脚本
- Java 反射机制
- SQL Server 2008中的分区表(二):如何添加、查询、修改分区表中的数据
- Mybatis核心对象及生命周期
- 编程第九十二天