[英]How define constructor implementation for an Abstract Class in Python?
我正在尝试使用具有默认行为的构造函数声明抽象类A
:所有子类都必须初始化成员self.n
:
from abc import ABCMeta
class A(object):
__metaclass__ = ABCMeta
def __init__(self, n):
self.n = n
但是,我不想让A
类被实例化,因为它是一个抽象类。 问题是,这实际上是允许的:
a = A(3)
这不会产生错误,而我希望它应该。
那么:如何在为构造函数定义默认行为的同时定义不可实例化的抽象类?
使__init__
成为抽象方法:
from abc import ABCMeta, abstractmethod
class A(object):
__metaclass__ = ABCMeta
@abstractmethod
def __init__(self, n):
self.n = n
if __name__ == '__main__':
a = A(3)
帮助:
TypeError: Can't instantiate abstract class A with abstract methods __init__
Python 3 版本:
from abc import ABCMeta, abstractmethod
class A(object, metaclass=ABCMeta):
@abstractmethod
def __init__(self, n):
self.n = n
if __name__ == '__main__':
a = A(3)
也有效:
TypeError: Can't instantiate abstract class A with abstract methods __init__
一个不太优雅的解决方案可能是这样的:
class A(object):
def __init__(self, n):
if self.__class__ == A:
raise Exception('I am abstract!')
self.n = n
用法
class B(A):
pass
a = A(1) # Will throw exception
b = B(1) # Works fine as expected.
您还应该使用@abc.abstractmethod
装饰器将方法定义为抽象方法。
您可以覆盖__new__
方法以防止直接实例化。
class A(object):
__metaclass__ = ABCMeta
def __new__(cls, *args, **kwargs):
if cls is A:
raise TypeError(
"TypeError: Can't instantiate abstract class {name} directly".format(name=cls.__name__)
)
return object.__new__(cls)
输出:
>>> A()
Traceback (most recent call last):
File "<ipython-input-8-3cd318a12eea>", line 1, in <module>
A()
File "/Users/ashwini/py/so.py", line 11, in __new__
"TypeError: Can't instantiate abstract class {name} directly".format(name=cls.__name__)
TypeError: TypeError: Can't instantiate abstract class A directly
您可以实现如下内容:
from abc import ABC
class A(ABC):
def __init__(self, n):
self.n = n
super(A,self).__init__()
实例化这个类会抛出一个错误
我不想让 A 类被实例化,因为它是一个抽象类。 问题是,这实际上是允许的
Python 本身不提供抽象类。 'abc' 模块提供定义抽象基类的基础结构。
抽象类是包含一个或多个抽象方法的类。 在您的情况下,代码仍然是一个抽象类,应该提供“无法实例化抽象类”行为。
如果您不想允许,程序需要更正:即添加装饰器@abstractmethod。 下面的代码在python 3.6中执行
from abc import ABC, abstractmethod
class Myabs(ABC):
def __init__(self, connection):
self.connection = connection
print("1. calling from base init : {}".format(self.connection))
super(Myabs, self).__init__()
@abstractmethod
def fun1(self, val):
pass
class D(Myabs):
def fun1(self, val="hi"):
print("calling from D: fun1")
object0 = Myabs('connection') # Python 3.6.9
输出:
ClassConcept/abs_class.py 回溯(最近一次调用最后一次):文件“ClassConcept/abs_class.py”,第 19 行,在 object0 = Myabs('connection') # Python 3.6.9 TypeError:无法用抽象实例化抽象类 Myabs方法乐趣1
进程以退出代码 1 结束
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.