Python descriptor 以及 内置property()函数
Python Descriptor
1, Python Descriptor是这样一个对象
它按照descriptor协议, 有这样的属性之一
def __get__(self, obj, type=None) # 会返回一个value
def __set__(self, obj, value) # 返回None
def __delete__(self, obj) # 返回None
这样的对象就是一个descriptor
2, descriptor的特性
假若有一个对象t, 我们去引用它的一个属性a
t.a
但是发现a是一个descriptor
那么不会返回a, 而是会去调用a相应的__get__, __set__, __delete__
那么什么情况调用那个呢?如下
- v = t.a <----> v = __get__(a, t)
- t.a = v <-----> __set__(a, t, v)
- del t.a <-----> __delete__(a, t)
3, descriptor是如何实现的
只有new-style objects或class的属性在被引用时,descriptor的特性才能起作用
从 object 派生的类就是 new-style class
class T(object):
pass
那么这大概是怎么回事呢?
是因为object有__getattribute__属性, 这个属性的实现确保了descriptor机制
所以如果我们重写了__getattribute__, 那么就可以消除descriptor机制
__getattribute__是如何实现的,以后探讨, 参考2中有一点点例子
内置函数 property()
Python有内置property()函数, 它可以直接做函数,也可以用来做装饰器, 它的使用方式如下, 例子来自参考3
class Test(object):
def getx(self):
return self._x
def setx(self, v):
self._x = v
def deletex(self):
del self._x x = property(getx, setx, deletex, ''' __doc__''')
而上面的代码等价于下面的
class Test(object):
@property
def x(self):
return self._x @x.setter
def x(self, v):
self._x = v @x.deleter
def x(self):
del self._x
对于Test的x属性,可以这么用
t = Test()
t.x = 5
print t.x
del t.x
那么为什么property()可以这么用,尤其是第二种中, x.setter和 x.deleter还可以做装饰器呢?
首先我们要先明白装饰器是什么
property()会返回一个Property对象, 然后我们来看一个用Python模拟的Property类的实现, 摘自参考1
class Property(object):
"Emulate PyProperty_Type() in Objects/descrobject.c" def __init__(self, fget=None, fset=None, fdel=None, doc=None):
self.fget = fget
self.fset = fset
self.fdel = fdel
if doc is None and fget is not None:
doc = fget.__doc__
self.__doc__ = doc def __get__(self, obj, objtype=None):
if obj is None:
return self
if self.fget is None:
raise AttributeError("unreadable attribute")
return self.fget(obj) def __set__(self, obj, value):
if self.fset is None:
raise AttributeError("can't set attribute")
self.fset(obj, value) def __delete__(self, obj):
if self.fdel is None:
raise AttributeError("can't delete attribute")
self.fdel(obj) def getter(self, fget):
return type(self)(fget, self.fset, self.fdel, self.__doc__) def setter(self, fset):
return type(self)(self.fget, fset, self.fdel, self.__doc__) def deleter(self, fdel):
return type(self)(self.fget, self.fset, fdel, self.__doc__)
认真看看就明白了
- Property对象是Descriptor
- Property.setter 和 Property.deleter 都是装饰器,他们和property一样,都是返回Property()对象,不同的是 @property设置 fget , setter和 deleter分别设置 fset, 和 fdel
-----------------------------------
很好的学习参考:
1, http://stackoverflow.com/questions/17330160/python-how-does-decorator-property-work
2, http://docs.python.org/3.2/howto/descriptor.html
3, http://docs.python.org/3.2/library/functions.html#property
Python descriptor 以及 内置property()函数的更多相关文章
- python 中的内置高级函数
1.map(function,iterable) map是把迭代对象依次进行函数运算,并返回. 例子: map返回的十分map对象,需要list()函数转化. 2.exec()函数 执行储存在字符串或 ...
- python 常见的内置函数
内置函数 接下来,我们就一起来看看python里的内置函数.截止到python版本3.6.2,现在python一共为我们提供了68个内置函数.它们就是python提供给你直接可以拿来使用的所有函数.这 ...
- python之路——内置函数和匿名函数
阅读目录 楔子 内置函数 匿名函数 本章小结 楔子 在讲新知识之前,我们先来复习复习函数的基础知识. 问:函数怎么调用? 函数名() 如果你们这么说...那你们就对了!好了记住这个事儿别给忘记了,咱们 ...
- python学习交流 - 内置函数使用方法和应用举例
内置函数 python提供了68个内置函数,在使用过程中用户不再需要定义函数来实现内置函数支持的功能.更重要的是内置函数的算法是经过python作者优化的,并且部分是使用c语言实现,通常来说使用内置函 ...
- python常用的内置函数哈哈
python常用的内置函数集合做一个归类用的时候可以查找 abs 返回数字x的绝对值或者x的摸 all (iterable)对于可迭代的对象iterable中所有元素x都有bool(x)为true,就 ...
- python常用的内置函数
python常用的内置函数集合做一个归类用的时候可以查找- abs 返回数字x的绝对值或者x的摸 - all (iterable)对于可迭代的对象iterable中所有元素x都有bool(x)为tru ...
- 十六. Python基础(16)--内置函数-2
十六. Python基础(16)--内置函数-2 1 ● 内置函数format() Convert a value to a "formatted" representation. ...
- 十五. Python基础(15)--内置函数-1
十五. Python基础(15)--内置函数-1 1 ● eval(), exec(), compile() 执行字符串数据类型的python代码 检测#import os 'import' in c ...
- Python的常用内置函数介绍
Python的常用内置函数介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.取绝对值(abs) #!/usr/bin/env python #_*_coding:utf-8_ ...
随机推荐
- 1.0Tensorflow中出现编译问题的解决方案
跑简单tf例程的时候遇到这个 sess = tf.Session(),I tensorflow/core/platform/cpu_feature_guard.cc:] Your CPU suppor ...
- Help Jimmy POJ - 1661 数字三角DP
题意:中文 https://vjudge.net/problem/POJ-1661 题解:设两个dp数组,dpl[i]存 从第i块板左边到地上所花的最短时间,dpr[i]存右边的. 将所有板按高度排序 ...
- kubernetes实战(十四):k8s持久化部署gitlab集成openLDAP登录
1.基本概念 使用k8s安装gitlab-ce,采用GlusterFS实现持久化(注意PG使用的是NFS存储,使用动态存储重启postgresql的pod后无法成功启动pg,待解决),并集成了open ...
- innodb next-key lock引发的死锁
innodb的事务隔离级别是可重复读级别且innodb_locks_unsafe_for_binlog禁用,也就是说允许next-key lock CREATE TABLE `LockTest` ( ...
- (3.2)mysql基础深入——mysql源码阅读工具安装与应用
(3.2)mysql基础深入——mysql源码阅读工具安装与应用 关键字:mysql源码阅读工具 工具列举:一般多用[1][2][3]吧 [1]source insight [2]写字板/记事本 UE ...
- 腾讯在线文档发布:实现QQ、微信多平台多人协作编辑
18日,腾讯宣布推出专注多人协作的在线文档产品—腾讯文档,据介绍,腾讯文档是一款支持随时随地创建.编辑的多人协作式在线文档工具,拥有一键翻译.实时股票函数和浏览权限安全可控等功能,以及打通QQ.微信等 ...
- 【剑指offer】替换空格
一.题目: 请实现一个函数,将一个字符串中的空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. 二.思路: Python代码,先 ...
- visual studio code 的必装推荐插件plugin, vscode, vsc
An Old Hope Theme (theme, 推荐,且推荐它的 classic theme,安装后在颜色选项里选择,该插件的定制见文末) Cobalt2 (theme) Drac ...
- Spark Sort-Based Shuffle具体实现内幕和源码详解
为什么讲解Sorted-Based shuffle?2方面的原因:一,可能有些朋友看到Sorted-Based Shuffle的时候,会有一个误解,认为Spark基于Sorted-Based Shuf ...
- [py][mx]django课程模型
课程模型分析 分3个表 先设计课程表, 这是1 在设计lesson表,添加一个外键,course. 课程 1 course 章节 n lesson 视频 n video 资源 n coursereso ...