第一个函数是调用它的实例,obj是指去访问属性所在的方法,最后一个type是一个可选参数 , 通常为None(这个有待于进一步的研究)
例如给定类X和实例x,调用x.foo,等效于调用:
type(x).__dict__["foo"].__get__(x,type(x))
调用X.foo,等效于调用:
type(x).__dict__["foo"].__get__(None,type(x))
第二个函数__set__的标准定义是__set__(self,obj,val) , 它非常接近于JavaBean的set方法,其中最后一个参数是要赋予的值
第三个函数__del__的标准定义是__del__(self,obj),它非常接近Java中Object的Finailize()方法,指
Python在回收这个垃圾对象时所调用到的析构函数,只是这个函数永远不会抛出异常 。因为这个对象已经没有引用指向它,抛出异常没有任何意义 。
接下来,我们来一一比较这些优先级.
首先来看类属性
[python] view plain copy
# -*- coding:utf-8 -*-
'''''
Created on 2013-3-29
@author: naughty
'''
class A(object):
foo=3
print A.foo
a=A()
print a.foo
a.foo=4
print a.foo
print A.foo
上面这段代码的输出如下:
3
3
4
3
从输出可以看到 , 当我们给a.foo赋值的时候,其实与类实例的那个foo是没有关系的 。a.foo=4 这句话给a对象增加了一个属性叫foo 。其值是4 。
最后两个语句明确的表明了 , 我们输出a.foo和A.foo的值,python函数是数据吗他们是不同的 。
但是为什么a=A()语句后面的print
a.foo输出了3呢python函数是数据吗?这是因为根据搜索顺序找到了类属性 。当我们执行a.foo=4的时候,我们让a对象的foo属性指向了4这个对象 。但是并没有改变
类属性foo的值 。所以最后我们print A.foo的时候,又输出了3 。
[python] view plain copy
# -*- coding:utf-8 -*-
'''''
Created on 2013-3-29
@author: naughty
'''
class A(object):
foo=3
a=A()
a.foo=4
print a.foo
del a.foo
print a.foo
上面的代码,我给a.foo赋值为4 , 在输出一次之后就del了 。两次输出,第一次输出的是a对象的属性 。第二次是类属性 。不是说类属性的优先级比
实例属性的高吗 。为啥第一次输出的是4而不是3呢?还是上面解释的原因 。因为a.foo与类属性的foo只是重名而已 。我们print
a.foo的时候,a的foo指向的是4 , 所以输出了4 。
------------------------------------
然后我们来看下数据描述符这一全新的语言概念 。按照之前的定义,一个实现了__get__,__set__,__del__的类都统称为数据描述符 。我们来看下一个简单的例子 。
[python] view plain copy
# -*- coding:utf-8 -*-
'''''
Created on 2013-3-29
@author: naughty
'''
class simpleDescriptor(object):
def __get__(self,obj,type=None):
pass
def __set__(self,obj,val):
pass
def __del__(self,obj):
pass
class A(object):
foo=simpleDescriptor()
print str(A.__dict__)
print A.foo
a=A()
print a.foo
a.foo=13
print a.foo
上面例子的输出结果如下:
[plain] view plain copy
{'__dict__': attribute '__dict__' of 'A' objects, '__module__': '__main__', 'foo': __main__.simpleDescriptor object at 0x005511B0, '__weakref__': attribute '__weakref__' of 'A' objects, '__doc__': None}
None
None
None
从输出结果看出,print语句打印出来的都是None 。这说明a.foo都没有被赋值内容 。这是因为__get__函数的函数体什么工作都没有做 。直接是pass 。此时 , 想要访问foo,每次都没有返回内容,所以输出的内容就是None了 。
推荐阅读
- 快手直播怎么分享全景声音,快手音频直播间怎么开
- flutter监听某个值变化,flutter退出应用监听
- 小米电视订的会员怎么取消,小米电视订的会员怎么取消自动续费
- 关于磁盘的linux命令 linux磁盘操作命令
- .net开发wpf用的多吗,net5 wpf会跨平台吗
- 区块链的编写,区块链编写语言
- js怎么刷新代码片段,js刷新页面的语句
- c语言判断键盘状态函数 c语言怎么判断按键的状态
- 小程序上订单怎么取消掉,小程序下单怎么取消订单