23 Python class 抽象类
2016-12-23 17:51
225 查看
抽象基类
要定义抽象基类,需要使用abc模块。该模块定义了一个元类(ABCMeta)和一组装饰器@abstractmethod,@abstractproperty。可以按如下方式使用
from abc import ABCMeta,abstractmethod,abstractproperty class People: __metaclass__ = ABCMeta @abstractmethod def set_name(self): pass @abstractproperty def pro(self): pass
要定义抽象类,需要将元类设置为
ABCMeta。这一步是必须的,因为抽象类的实现离不开元类。在抽象类中,
@abstractmethod和@abstractproperty装饰的方法/特性其子类必须实现。
抽象类并不能直接实例化。
f = People() #TypeError: Can't instantiate abstract class Student with abstract methods pro, set_name
这一限制也适用于派生类。如果类Foo1继承了Foo,但是Foo1没有实现Foo中的抽象方法,当创建Foo1的实例时,会生成类似的错误。
class Student(People): pass f = Student() #TypeError: Can't instantiate abstract class Student with abstract methods pro, set_name
尽管抽象类会在实现的方法和特性上强制实施规则,但它不会对参数和返回值进行一致性检查。所以,抽象类不会检查子类是否使用了与抽象方法相同的参数和返回值。
虽然抽象类无法实例化,但是它可以决定子类中必须实现的方法和特性。而且,基类中的抽象方法/特性仍然可以从子类中调用。
class Student(People): def set_name(self,name): #参数个数不同 print super(Student,self).set_name()#调用基类中的抽象方法 print 'Student,set_name = %s'%name return True #返回值不同 def pro(self,tmp = ''): #参数不同,特性->方法也是可以的,因为特性是一种特殊的函数 print super(Student,self).pro #调用基类中的特性 print 'Student,pro,tmp = %s'%tmp return True #返回值不同
>>> f = Student() >>> f.set_name('xiaohong') None Student,set_name = xiaohong >>> f.pro() None Student,pro,tmp = Null
类注册
抽象基类支持对已经存在的类进行注册,使其属于该基类,使用register()进行注册。如向抽象基类A注册类B,
A.register(B)。
向抽象基类注册某个类时,对于注册类的实例,涉及抽象基类的类型检查操作(isinstance,issubclass)将返回True。
向抽象类注册某个类时,不会检查该类是否实现了抽象方法/特性。这种注册只影响类型检查,它不会向注册的类进行额外的错误检查。
from abc import ABCMeta,abstractmethod,abstractproperty class People(object): __metaclass__ = ABCMeta @abstractmethod def set_name(self): pass class Foo(object):#没有实现抽象方法set_name pass #print People,type(People),type(type(People)),People.__metaclass__ #print Foo,type(Foo),type(type(Foo)) f = Foo() print isinstance(f,People) #False print isinstance(f,Foo) #True print issubclass(Foo,People) #False print issubclass(Foo,object) #True print issubclass(People,object)#True People.register(Foo) #向People抽象基类注册,让Foo属于People print isinstance(f,People) #True print isinstance(f,Foo) #True print issubclass(Foo,People) #True print issubclass(Foo,object) #True print issubclass(People,object)#True
Python的内置类型组织到一个相对扁平的层次结构中。如int,float,可以看到他们直接继承自所有对象的根(object),而不是表示数字的中间基类。因此很难编写程序来根据类型检查和操作对象。抽象类机制解决了这一难题,它允许将已存在的对象组织到用户定义的类型层次结构中。
转载请标明出处,原文地址(http://blog.csdn.net/lis_12/article/details/53842299).
如果觉得本文对您有帮助,请点击‘顶’支持一下,您的支持是我写作最大的动力,谢谢。
相关文章推荐
- Python class 抽象类 与 元类 详解
- metaclass in python
- [初学python]新类(new-style class)
- Python Programming with the Java(TM) Class Libraries: A Tutorial for Building Web and Enterprise App
- Python入门的36个例子 之 23 -> Objects and References —— 复制引用还是复制实体对象
- Python[十四]:Class
- 接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?
- Python中的元类(metaclass)
- python Object And Class
- 接口与抽象类 (interface and abstract class)
- Python中的Class
- the Differences between abstract class & interface in C#接口和抽象类的区别
- Python的面向对象之class二看
- 利用metaclass实现python的aop
- Python天天美味(23) - enumerate遍历数组
- Python Type Class and Object的文章
- [Python]Queue -- A synchronized queue class
- 接口和抽象类浅析(Interface and abstract class)
- Abstract Class VS Interface | 抽象类VS接口
- 抽象类是否能够继承实体类(concrete class)?