为什么我不限制在Python 3.4中实例化抽象类?

时间:2014-09-27 17:25:31

标签: python abstraction python-3.4

我编写了一个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

现在我创建了另一个继承自abstractShape的类:
文件名: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
  1. 为什么会这样?这不是抽象的!是吗?
  2. 或者Python 3.4中是否有任何新的抽象方法?
  3. 任何人都可以给我链接python 3.4的官方文档吗?

1 个答案:

答案 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