python函数是数据吗的简单介绍( 三 )


[python] view plain copy
# -*- coding:utf-8 -*-
'''''
Created on 2013-3-29
@author: naughty
'''
class simpleDescriptor(object):
def __get__(self,obj,type=None):
return "hi there"
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
把__get__函数实现以下,就可以得到如下输出结果:
[plain] view plain copy
{'__dict__': attribute '__dict__' of 'A' objects, '__module__': '__main__', 'foo': __main__.simpleDescriptor object at 0x00671190, '__weakref__': attribute '__weakref__' of 'A' objects, '__doc__': None}
hi there
hi there
hi there
为了加深对数据描述符的理解,看如下例子:
[python] view plain copy
# -*- coding:utf-8 -*-
'''''
Created on 2013-3-29
@author: naughty
'''
class simpleDescriptor(object):
def __init__(self):
self.result = None;
def __get__(self, obj, type=None) :
return self.result - 10;
def __set__(self, obj, val):
self.result = val + 3;
print self.result;
def __del__(self, obj):
pass
class A(object):
foo = simpleDescriptor();
a = A();
a.foo = 13;
print a.foo;
上面代码的输出是
16
6
第一个16为我们在对a.foo赋值的时候 , 人为的将13加上3后作为foo的值 , 第二个6是我们在返回a.foo之前人为的将它减去了10 。
所以我们可以猜测,常规的Python类在定义get,set方法的时候,如果无特殊需求 , 直接给对应的属性赋值或直接返回该属性值 。如果自己定义类,并且继承object类的话,这几个方法都不用定义 。
-----------------
在这里看一个题外话 。
看代码
[python] view plain copy
# -*- coding:utf-8 -*-
'''''
Created on 2013-3-29
@author: naughty
'''
class simpleDescriptor(object):
def __init__(self):
self.result = None;
def __get__(self, obj, type=None) :
return self.result - 10;
def __set__(self, obj, val):
if isinstance(val,str):
assert False,"int needed! but get str"
self.result = val + 3;
print self.result;
def __del__(self, obj):
pass
class A(object):
foo = simpleDescriptor();
a = A();
a.foo = "13";
print a.foo;
上面代码在__set__ 函数中检查了参数val , 如果val是str类型的,那么要报错 。这就实现了我们上一篇文章中要实现的 , 在给属性赋值的时候做类型检查的功能 。
-----------------------------------------------
下面我们来看下实例属性和非数据描述符 。
[python] view plain copy
# -*- coding:utf-8 -*-
'''''
Created on 2013-3-29
@author: naughty
'''
class B(object):
foo = 1.3
b = B()
print b.__dict__
b.bar = 13
print b.__dict__
print b.bar
上面代码输出结果如下:
{}
{'bar': 13}
13
那么什么是非数据描述符呢?
简单的说,就是没有实现get,set,del三个方法的所有类 。
让我们任意看一个函数的描述:
def call():
pass
执行print dir(call)会得到如下结果:
[plain] view plain copy
['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']

推荐阅读