Pyhon中set,get,方法深入了解
来源:互联网 发布:19级研究所升级数据 编辑:程序博客网 时间:2024/05/01 04:14
</pre><pre name="code" class="python">首先要弄明白dir()和__dict__的区别:
class T(object): name = 'name' def hello(self): print 'hello' t = T()我们定义了一个类T和一个实例:
>>> dir(t) ['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'hello', 'name']
<pre name="code" class="python">
>>>dir(T)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'hello', 'name']
</pre><pre name="code" class="python">>>>t.__dict__
{}
</pre><pre name="code" class="python">>>>T.__dict__
dict_proxy({'__module__': '__main__', 'name': 'name', 'hello': <function hello at 0x7f5412fca5f0>, '__dict__': <attribute '__dict__' of 'T' objects>, '__weakref__': <attribute '__weakref__' of 'T' objects>, '__doc__': None})
可以看出,dir()里面存储的属性和 .__dict__里面存储的属性有着很大的区别, __dict__里面存储着自定义的属性,dir()除了自定义的属性还有python自动生成的,而属性查找get和属性设置set 都是基于__dict__来进行的,也就是说我们现在只用关心自定义的属性。
数据描述符,下面这个类产生的实例即是一个数据描述符(区分非数据描述符,数据描述符一定要带有__get__和__set__方法;如果只有__get__,没有__set__就是非数据描述符)
class Descriptor(object): def __get__(self, obj, type=None): return 'get', self, obj, type def __set__(self, obj, val): print 'set', self, obj, val
class T(object):
d=Descriptor()
t=T()
__get__方法:
__get__方法目的就是为了赋值,首先看下参数的意义,第一个self,是当前Descriptor 的实例,第二个obj,是拥有Descriptor 这个属性的对象,第三个type就是obj所属的类,举个例子说明:声明了t.d 则obj 就是t, type 记为T,所以t.d实际上是返回d.__get__(t,T) 的结果
如果T.d 则返回的是d.__get__(None,T) ....这是当类直接调用__get__方法的结果,
首先看下
>>>T.__dict
dict_proxy({'__dict__': <attribute '__dict__' of 'T' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'T' objects>, 'd': <__main__.Descriptor object at 0x7f5412fc8a10>, '__doc__': None})
>>>t.__dict__
{}
</pre>可以看到t中自定义属性还是没有,T.__dict__中的d是一个数据描述符 data descriptor(可以将数据描述符看成类T中特殊的方法,因为该方法本来就是一个类,而且包含着__get__和__set__方法)<p></p><p>那么我要查找t.d那怎么办呢?</p><p>首先,在t.__class__.__dict__中查找,就是T.__dict__中查找,发现了d,再判断d是否是data descriptor,是的话,就返回get方法的结果,所以返回的应该是</p><p></p><pre name="code" class="python">>>>t.d
('get', <__main__.Descriptor object at 0x7f5412fc8a10>, <__main__.T object at 0x7f5412fc8a50>, <class '__main__.T'>)
>>>T.d
('get', <__main__.Descriptor object at 0x7f5412fc8a10>, None, <class '__main__.T'>)
1. 首先在obj.__class__.__dict__中查找attr,也就是在obj的父类中查找,如果attr存在,并且是data descriptor, 则返回__get__方法的结果,如果没有,则在 祖先中查找,一步一步找,如果都没有,就进行第二步(这时候,只有两种情况,要不attr在父类中存在,且不是data descriptor,要不就是没在父类或者祖先中)
2.在obj.__dict__中查找,如果没找到,第三步
3.回到父类中,在obj.__class.__dict__中查找,这时候要求没那么高了,不要求是数据描述符,只要有就找到,如果父类没有,去祖先那里找
4.如果还没找到,sorry,无能为力了,如果没有异常处理,就会直接出错卡出来。
这个我们来验证一下以往的一个简单例子
class A(object): A.name='hello'a=A()
当给a.name='nihao'后,现在要查找a.name. 首先在父类A中搜索,确实有a,但是a 并不是数据描述符,所以回到a.__dict___中搜索,所以会所搜到 ' nihao' .
如果del a.name后,那么首先在父类A中搜索,确实有a,但是a 并不是数据描述符,所以回到a.__dict___中搜索,然而也没有搜索到 name, 因为我们已经删除了,所以再回到父类中搜索,这时候要求没那么高,搜索到了name ,值是 'hello', 所以会输出 ‘hello'
__set__方法
类似于__get__方法,我们首先给出赋值策略,再来详细例子介绍: 给obj.attr=value.
1.查找obj.__class__.__dict__,如果attr存在并且是个data descriptor , 则调用attr的__set__方法,如果不存在,现在祖先中搜索,如果实在没有,则到第二步
2. 这时候说明attr不存在或者不是数据描述符, 则直接obj.__dict__['attr']=value
考虑下调用t.d='scut' 和调用 T.d= 'SCUT' 有什么区别呢?
>>>t,d='scut'
set <__main__.Descriptor object at 0x7f5412fc8a10> <__main__.T object at 0x7f5412fc8a50> scut很明显,调用了描述符中的__set__方法,因为在父类中查找d的时候,就已经发现 d 是一个数据描述符,则直接调用数据描述符的__set__方法
>>>T.d='SCUT'
>>>T.__dict__
dict_proxy({'__dict__': <attribute '__dict__' of 'T' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'T' objects>, 'd': 'hello', '__doc__': None})
class A(object): A.name='hello'a=A()
- Pyhon中set,get,方法深入了解
- C#中 get set 方法
- iOS 中 set,get方法
- pyhon-字典的get()与setdefault()方法
- 深入了解隐式属性和带实现值属性的区别(属性中get{},set{}访问器小解)
- DataBinding中get,set方法的使用
- as3.0 中get 和 set方法
- java中set()和get()方法理解
- java中获取set和get方法
- Java中获取set和get方法
- C#中get与set方法
- oc中get set 方法的实现
- 在IOS中创建get,set方法
- object-c中get/set方法
- JavaScript中set与get方法用法
- oc中类的set get方法
- idea中get\set方法快捷添加
- PHP:魔术方法set和get的深入特性分析
- Dom4j解析xml使用方法
- 光标问题
- 电脑装系统之UltraIso(软碟通)
- Struts2学习
- 项目启动时,提示spring配置文件未知的utf-8编码
- Pyhon中set,get,方法深入了解
- EL表达式取Map,List值的总结
- 利用手机gps获取经纬信息定位
- leetcode_118 Pascal Triangle
- UI控件--ListView补充:包含多个子项布局的列表
- 【日常吐槽 · 第二期】向cocos的更新速度致敬
- 套接字相关
- 学习java前七天的总结
- MVC- View和Controller之间的传值