免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3792 | 回复: 0
打印 上一主题 下一主题

python Descriptor学习的认识 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-01-21 15:35 |只看该作者 |倒序浏览

                                最近看django源码的时候发现了python的descriptor,以前从来没有涉及过,(python的基础真是差啊,我),所以来学习一下。
参考了:http://users.rcn.com/python/download/Descriptor.htm
      http://blog.chinaunix.net/u/23216/showart_189009.html
      http://www.javaeye.com/wiki/Python/1362-python-39-s-descriptor
      http://docs.python.org/reference/datamodel.html#implementing-descriptors
descriptor实际上就是一个类的属性,只不过这个属性定义了__get__,__set__,__del__这三个方法中的一个或者多个(最少要有__get__),然后当这个类的对象调用这个属性的时候就会相应的调用__get__或者__set__或者__del__。只定义了__get__方法的descriptor是non-data descriptor,定义了__set__的是data-descriptor。
descriptor只能被一个新式的类或者类对象调用。(新式的类就是从objct或者type继承的类)。
类和类的对象都有__dict__,调用类对象的属性时:对于obj.x,优先查找obj.__dict__["x"],如果找不到,再查找class.__dict__["x"];调用类的属性时;对于class.x,直接查找class.__dict__["x"];obj.__dict__与class.__dict__可以拥有同名的属性;obj.x=10,将无条件的更新obj.__dict__;class.x=10,将无条件的更新class.__dict__。这里在掉用__dict__['x']的时候按照以下优先级:
data descriptor高于obj.__dict__['x']高于non-data descriptor。
我自己做了一些实验,感觉和javaeye以及chinaunix里面的两篇文章多少都有一些不一样(虽然这两篇文章好些写的一些细节也不一样)。
代码如下:(data-descriptor)
               
               
                #coding:utf-8
class AA(object):
    def __init__(self):
        self.value = 25
    def __get__(self, ownerobj, ownerclass):
        print "it is in ", ownerobj, "get"
        print "value is ", str(self.value)
        return self.value
    def __set__(self, ownerobj, value):
        print "it is in ", ownerobj, "set"
        print "original value is ", self.value
        print "now value is ", value
        self.value = value        
    def __delete__(self, ownerobj):
        pass
class CC(object):
    x = 5
    aobj = AA()
c = CC()
CC.aobj
c.aobj
print ">>>"*3
c.aobj = 15         #因为是data descriptor,而且c.__dict__中没有aobj这个键名,所以这里调用的是CC.__dict__['aobj'].__set__
CC.aobj              #这里调用的是CC.__dict__['aobj'].__get__
c.aobj               #因为c.__dict__中没有aobj这个键名,所以这里调用的是CC.__dict__['aobj'].__get__
print ">>>"*3        #注意:以下三行的解释可能有误,里买的值是对的,但是没有打印动作发生,不知道问什么,希望知道的高手给个解答。
CC.aobj = 35         #因为是data descriptor,而且c.__dict__中没有aobj这个键名,所以这里调用的是CC.__dict__['aobj'].__set__
CC.aobj              #这里调用的是CC.__dict__['aobj'].__get__,值是35。
c.aobj               #因为c.__dict__中没有aobj这个键名,所以这里调用的是CC.__dict__['aobj'].__get__,值是35。
运行结果为:
it is in  None get
value is  25
it is in   get
value is  25
>>>>>>>>>
it is in   set
original value is  25
now value is  15
it is in  None get
value is  15
it is in   get
value is  15
>>>>>>>>>
non-data descriptor代码为:
#coding:utf-8
class AA(object):
    def __init__(self):
        self.value = 25
    def __get__(self, ownerobj, ownerclass):
        print "it is in ", ownerobj, "get"
        print "value is ", str(self.value)
        return self.value
#        def __set__(self, ownerobj, value):
#                print "it is in ", ownerobj, "set"
#                print "original value is ", self.value
#                print "now value is ", value
#                self.value = value
        
#    def __delete__(self, ownerobj):
#         pass
class CC(object):
    x = 5
    aobj = AA()
c = CC()
CC.aobj
c.aobj
print ">>>"*3
c.aobj = 15     #因为是non-data descriptor直接设置了c.__dict__
CC.aobj         #调用的是CC.__dict__['aobj'].__get__,他返回的是关于CC类的,而不是上面对c设置的15
c.aobj          #因为是non-data descriptor,他调用的是c.__dict__中的值,所以没有print行为发生
print ">>>"*3
CC.aobj = 35    #设置的是CC.__dict__中的值
CC.aobj          #在这里是从CC.__dict__中直接取的属性值,所以没有print行为发生他的值是刚才设置的35
c.aobj           #因为是non-data descriptor,所以这里调用的是c.__dict__中的值,没有print行为发生。其值上面c.aobj=15设置的15
运行结果为:
it is in  None get
value is  25
it is in   get
value is  25
>>>>>>>>>
it is in  None get
value is  25
>>>>>>>>>
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/103690/showart_2156248.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP