Python核心编程笔记 - 第13章 面向对象编程(二)
描述符严格来说描述符实际上可以是任何新式类但这个类必须至少要实现以下3个特殊方法中的一个__get__(),__set__(),__delete__().同时实现__get__()和__set__()的类被称作数据描述符并不是所有的描述符都实现了__set__()方法因此算非数据描述符。优先级别类属性数据描述符实例属性非数据描述符默认为__get__()示例代码classSampleProxy(object):def__get__(self,obj,typNone):print(get into __get__() method)return100## always return 100def__set__(self,obj,val):print(in __set__() method)self.obj200## always set 200 to it, not valclassC1(object):ffSampleProxy()c1C1()c1.ffhello# in __set__() methodprint(c1.ff)# get into __get__() method \n 100metaclass (元类)metaclass是用于创建类的类它用来定义一个类该被如何创建。metaclass一般用于创建类。在执行类的定义时解释器必须要知道这个类的正确的metaclass。解释器会先去寻找类属性__metaclass__若此属性存在就以此属性作为元类若没有则向上查找父类中的__metaclass__。所以新式类若没有任何父类就会从对象或类型中继承。若仍然没有发现__metaclass__属性解释器会检查名字为__metaclass__的全局变量若有就使用它。否则该类就是一个传统类。传统类使用types.ClassType作为元类。若你定义了一个传统类并且设置它的__metaclass__ type这就是在将这个传统类升级为一个新式类。metaclass通常传递3个参数到构造器name、bases从基类继承数据的元组 和 attrd类的属性字典示例程序fromwarningsimportwarnclassReqStrSugRepr(type):def__init__(cls,name,bases,attrd):super(ReqStrSugRepr,cls).__init__(name,bases,attrd)if__str__notinattrd:raiseTypeError(Class requires overriding of __str__())if__repr__notinattrd:warn(Class suggests overriding of __repr__()\n,stacklevel3)print(*** Defined ReqStrSugRepr (meta)class)classFoo(object):__metaclass__ReqStrSugReprdef__str__(self):returnInstance of class: ,self.__class__.__name__def__repr__(self):returnself.__class__.__name__print(***Defined Foo class)# will be OkayclassBar(object):__metaclass__ReqStrSugReprdef__str__(self):returnInstance of class: ,self.__class__.__name__print(***Defined Bar class)# will have a warnclassFooBar(object):__metaclass__ReqStrSugRepr# will get TypeErrorprint(*** Defined FooBar class)(END)