#通过子类实例父类
from abc import ABC,abstractmethod,abstractproperty class Drawable(ABC): @abstractproperty def size(self): pass @abstractmethod def draw(self,x,y,scale=1.0): pass def double_draw(self,x,y): self.draw(x,y,scale=2.0) class Circle(Drawable): def draw(self, x, y, scale=1.0): print(x*scale,y*scale) @property def size(self): return 'Circle size' c=Circle() print(dir(c)) c.draw(1,2) c.double_draw(1,2)
----
#output:
['__abstractmethods__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_abc_impl', 'double_draw', 'draw', 'size']
1.0 2.0
2.0 4.0
----
#父类不能直接实例调用
class Drawable(ABC): @abstractproperty def size(self): pass @abstractmethod def draw(self,x,y,scale=1.0): pass def double_draw(self,x,y): self.draw(x,y,scale=2.0) class Circle(Drawable): def draw(self, x, y, scale=1.0): print(x*scale,y*scale) @property def size(self): return 'Circle size' b=Drawable() b.draw(1,2)
----
#output:
Traceback (most recent call last):
File "D:/djangocode/Celery_ttoia/app/tests.py", line 50, in
b=Drawable()
TypeError: Can't instantiate abstract class Drawable with abstract methods draw, size
----
抽象方法是父类的一个方法, 父类没有实现这个方法, 父类是不可以实例化的. 子类继承父类, 子类必须实现父类定义的抽象方法, 子类才可以被实例化. Python中的abc提供了@abstractmethod装饰器实现抽象方法的定义
from abc import ABC, abstractmethod class Foo(ABC): @abstractmethod def fun(self): """ 你需要在子类中实现该方法, 子类才允许被实例化 """ class SubFoo(Foo): def fun(self): print("子类实现父类的抽象方法") def go(self): print(666) if __name__ == "__main__": sf = SubFoo() sf.fun() ---- #outout: 子类实现父类的抽象方法
当子类未重写父类fun方法时:
from abc import ABC, abstractmethod class Foo(ABC): @abstractmethod def fun(self): """ 你需要在子类中实现该方法, 子类才允许被实例化 """ class SubFoo(Foo): # def fun(self): # print("子类实现父类的抽象方法") def go(self): print(666) if __name__ == "__main__": sf = SubFoo() sf.go() ---- #output: Traceback (most recent call last): File "D:/djangocode/Celery_ttoia/app/tests.py", line 122, insf = SubFoo() TypeError: Can't instantiate abstract class SubFoo with abstract methods fun ----