代码改变世界

python class 常用内置方法分析

2017-02-28 13:59  老左的博客  阅读(1547)  评论(0编辑  收藏  举报
 1 class ABC(object):
 2     def __init__(self):
 3         self.value = {}
 4         
 5     def __setattr__(self, name, val):
 6         """ x.__setattr__('name', val) <==> x.name = val """
 7         print 'call __setattr__: name={0}, val={1}'.format(name, val)
 8         object.__setattr__(self, name, val)
 9         
10     def __getattribute__(self, name):
11         """ x.__getattribute__('name') <==> x.name """
12         print 'call __getattribute__: name={0}'.format(name)
13         return object.__getattribute__(self, name)
14             
15     def __getattr__(self, name):
16         """
17         called __getattr__ when call __getattribute__ raise AttributeError exception
18         """
19         print 'call __getattr__: name={0}'.format(name)
20         return None
21     
22     def __delattr__(self, name):
23         """ x.__delattr__('name') <==> del x.name """
24         print 'call __delattr__: name={0}'.format(name)
25         object.__delattr__(self, name)
26     
27     def __setitem__(self, name, val):
28         """ x.__setitem__(name, val) <==> x[name]=val """
29         print 'call __setitem__: name={0}, val={1}'.format(name, val)
30         self.value[name] = val
31         
32     def __getitem__(self, name):
33         """ x.__getitem__(name) <==> x[name] """
34         print 'call __getitem__: name={0}'.format(name)
35         try:
36             return self.value[name]
37         except KeyError:
38             raise KeyError(name)
39             
40     def __delitem__(self, name):
41         """ x.__delitem__(name) <==> del x[name] """
42         print 'del __getitem__: name={0}'.format(name)
43         del self.value[name]
44         
45     def __iter__(self):
46         """ x.__iter__() <==> iter(x) """
47         for item in self.value:
48             yield item
49         raise StopIteration

class ABC 从 object 继承,object 已经定义了 __setattr__,__getattribute__,__delattr__ 方法,这里重载只是打印日志,方便跟踪调用。

abc = ABC()
abc.x = 1

打印:

call __setattr__: name=value, val={}

call __setattr__: name=x, val=1

 

__setattr__ 方法调用了两次,因为实例化abc的时候会首先调用__init__ 方法,对value属性赋值,接着对x属性赋值

 

print abc.x

打印:

call __getattribute__: name=x

1

 

如果访问abc没有的属性y,__getattribute__将会抛出AttributeError异常,如果class ABC重载了__getattr__方法,__getattr__将会被调用,return None,否则__getattr__不会被调用。

print abc.y

打印:

call __getattribute__: name=y

call __getattr__: name=y

None

 

class ABC 定义了 __setitem__ __getitem__ __delitem__ 方法,支持 self[key] 操作,这几个方法object没有实现

 

abc['y'] = 2
print abc['y']

打印:

call __setitem__: name=y, val=2

call __getattribute__: name=value

call __getitem__: name=y

call __getattribute__: name=value

2

 

class ABC 定义了 __iter__ 方法,支持迭代操作

 

1 abc = ABC()
2 abc.x = 1
3 abc['y'] = 2
4 abc['z'] = 3
5 for item in abc:
6     print item

打印:

call __getattribute__: name=value

y

z

 

class ABC 重载了 __delattr__ 并且定义了 __delitem__ 方法,支持 del abc.x,del abc[y]操作,删除不存在的属性和key将会抛出异常。

 

1 print abc.__dict__
2 del abc.x
3 del abc['y']
4 print abc.__dict__

打印:

{'x': 1, 'value': {'y': 2, 'z': 3}}

call __delattr__: name=x

del __getitem__: name=y

{'value': {'z': 3}}