我编写了一个Python脚本,并且发现Python 3.4并不限制抽象类在Python 2.7.8的情况下被实例化。
这是我名为Shape.py
的文件中的抽象类。
from abc import ABCMeta, abstractmethod
class Shape:
__metaclass__ = ABCMeta # Making the class abstract
def __init__(self):
pass:
@abstractmethod
def getArea(self):
print("You shouldn't have called me.")
return None
现在我创建了另一个继承自abstract
类Shape
的类:
文件名:Circle.py
from Shape import Shape
class Circle(Shape):
PI = 3.141
def __init__(self, radius=0):
self.radius = radius
def getArea(self): # Overriding it from Shape class
return self.PI * self.radius ** 2
现在在Main.py
:
from Shape import Shape
from Circle import Circle
shape = Shape() # This gave me errors in Python 2.7.8 but not in Python 3.4
shape2 = Circle(5)
print("Area of shape = "+str(shape.getArea())) # This should have not been executed.
print("Area of circle = "+str(shape2.getArea()))
这个Main.py
在Python2.7.8中给出了注释区域的错误,但在Python3.4上工作正常
Python3.4上的输出:
You shouldn't have called me
Area of shape = None
Area of circle = 78.525
答案 0 :(得分:8)
在Python 3中,您以不同方式声明元类:
class Shape(metaclass=ABCMeta):
请参阅Customizing class creation documentation:
可以通过在类定义行中传递
metaclass
关键字参数,或者从包含此类参数的现有类继承来自定义类创建过程。
Python 3的abc
module documentation中的所有示例也使用正确的表示法。
这被改为让元类有机会比Python 2更早地参与类创建;见PEP 3115。
__metaclass__
属性不再具有特殊含义,因此您实际上并没有创建适当的抽象类。
使用Python 3.4进行演示:
>>> from abc import ABCMeta, abstractmethod
>>> class Shape(metaclass=ABCMeta):
... @abstractmethod
... def getArea(self):
... print("You shouldn't have called me.")
... return None
...
>>> Shape()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Shape with abstract methods getArea