13.16 新式类的高级特性(Python 2.2+)
13.16.1 新式类的通用特性
尽管isinstance()很灵活,但它没有执行“严格匹配”比较——如果obj是一个给定类型的实例或其子类的实例,也会返回True。但如果想执行严格匹配,你仍然需要使用is操作符。
13.16.2 __slots__类属性
__dict__属性跟踪所有实例属性。
__slots__是一个类变量,由一序列型对象组成,由所有合法标识构成的实例属性的集合来表示。它可以是一个列表,元组或可迭代对象。也可以是标识实例所拥有的唯一的属性的简单字符串。任何试图创建一个不在__slots__中的名字的实例属性都将导致AttributeError异常。
>>> class C(object):
... __slots__= ("Att1", "Att2")
...
>>> c = C()
>>> c.Att1 = 2
>>> c.Att1
2
>>> C.Att1
<member 'Att1' of 'C' objects>
>>> type(C.Att1)
<type 'member_descriptor'>
>>> c.Att3 = 3
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
AttributeError: 'C' object has no attribute'Att3'
>>>
这种特性的主要目的是节约内存。其副作用是某种类型的“安全”,它能防止用户随心所欲的动态增加实例属性。带__slots__属性的类定义不会存在__dict__了(除非你在__slots__中增加’__dict__’元素)。
13.16.3 __getattribute__()特殊方法
Python类有一个名为__getattr__()的特殊方法,它仅当属性不能在实例的__dict__或它的类(类的__dict__),或者祖先类(其__dict__)中找到时,才被调用。
__getattribute__()使用起来类似__getattr__(),不同之处在于,当属性被访问时,它就一直都可以被调用,而不局限于不能找到的情况。
为了安全地访问它所需要的属性,你总是应该调用祖先类的同名方法;比如,super(obj,self)__getattribute__(attr)。此特殊方法只在新式类中有效。
>>> class B(object):
... version= 2.0
... def__init__(self,x):
... self.x= x
... self.y= 200
... def__getattribute__(self,obj):
... ifobj == 'x':
... return'xxx'
... else:
... raiseAttributeError
... def__getattr__(self,obj):
... return'defaultValue'
...
>>> b = B(100)
>>> print b.x
xxx
>>> print b.y
defaultValue
>>> print b.count
defaultValue
>>>