首页 > 代码库 > python 中关于descriptor的一些知识问题

python 中关于descriptor的一些知识问题

这个问题从早上日常扫segmentfault上问题开始

有个问题是

class C(object):    @classmethod    def m():        passm()是类方法,调用代码如下:C.m()但我想当成属性的方式调用,像这样:C.m请问该怎么弄呢? 请最好提供个简单的例子, 多谢!

 

这里我开始误会了他的意思,以为他是想直接使用C().m调用这个方法,如果是这样,直接将装饰器@classmathod改成@property就可以达到效果了。

但是这里他想要达到的效果是C.m 也就是说在不实例化C对象的情况下去调用m方法 有点类似即使用classmathod然后在这个基础上又调用property方法

 

我想了很久,没有在以前的编码中遇到过,所以来了兴致。

 

在广泛查找资料之后,我发现跟一个叫descriptor protocol的概念有关。

什么是descriptor?官方文档给的简介是:

In general, a descriptor is an object attribute with “binding behavior”, one whose attribute access has been overridden by methods in the descriptor protocol. Those methods are __get__()__set__(), and __delete__(). If any of those methods are defined for an object, it is said to be a descriptor

通常来说,一个descriptor就是一个绑定行为的对象,一个属性会被描述协议中的方法覆盖。那些方法包括__get__(), __set__()和__delete__().如果任何上面的那些方法出现在了你定义的object中,那么我们就说他是一个descriptor。

换句话来说,如果你定义一个class方法,然后class方法中包含了__get__,__set__和__delete__方法中的任何一个,那么这个类就是一个descriptor。

相信绝大多数人都是用过上面提到的property方法,但是不知道有没有盆友仔细看过property的源码,其实property就是一个典型的descriptor。

 

说这么多也不明白来复现一下上面的问题怎么解决

class ClassPro(object):    def __init__(self, function):        self.run = function    def __get__(self, instance, owner):        return self.run(owner)class a(object):    def pp(self):        print say something    pp = ClassPro(pp)a.pp
output:say something

可以看到上面我实现了一个自定义的新式类ClassPro用来装饰下面a类里面的函数pp 。CP实现了__get__方法所以他是一个descriptor,descriptor一旦实现,会覆盖掉原有的从__dict__里面寻找属性的方式。这里我引用别人博客里面翻译过来的doc

通常对一个实例的属性的访问操作,如get, set, delete是通过实例的__dict__字典属性进行的,
例如,对于操作a.x,会一个查找链从a.__dict[‘x‘](实例的字典),再到type(a).__dict__[‘x‘](类的
字典),再到type(a)的父类的字典等等。
如果一个对象同时定义了__get__,__set__方法,被看作是data descriptor;只定义了__get__,被称
为non-data descriptor。如果实例字典中有一个key和data descriptor同名,那么查找时优先采用
data descriptor;如果实例字典中有一个key和non-data descriptor同名,那么优先采用实例字典的
方法。

大概就是这样。

 

Preference:

http://stackoverflow.com/questions/17330160/how-does-the-property-decorator-work  how-does-the-property-decorator-work 

http://www.cnblogs.com/btchenguang/archive/2012/09/17/2689146.html  python中基于descriptor的一些概念(上)

http://www.cnblogs.com/btchenguang/archive/2012/09/18/2690802.html#3416935  python中基于descriptor的一些概念(下)

https://docs.python.org/2.7/howto/descriptor.html  Descriptor HowTo Guide

http://stackoverflow.com/questions/128573/using-property-on-classmethods  Using property() on classmethods

python 中关于descriptor的一些知识问题