【问题标题】:Why am I not restricted from instantiating abstract classes in Python 3.4?为什么我不限制在 Python 3.4 中实例化抽象类?
【发布时间】:2014-09-27 17:25:31
【问题描述】:

我编写了一个 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官方文档的链接?

【问题讨论】:

  • 你可以使用 Six.add_meta_class 装饰器来支持 Python 2 & 3

标签: python abstraction python-3.4


【解决方案1】:

在 Python 3 中,您声明元类的方式不同:

class Shape(metaclass=ABCMeta):

Customizing class creation documentation

可以通过在类定义行中传递 metaclass 关键字参数或从包含此类参数的现有类继承来自定义类创建过程。

abc module documentation for Python 3 中的所有示例也使用正确的表示法。

这已被更改,以使元类有机会比 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

【讨论】:

  • 谢谢。这行得通。我真傻。您能否也回答我的第三个子问题(已编辑问题)?提前感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2015-03-19
  • 1970-01-01
  • 1970-01-01
  • 2014-03-08
  • 2019-09-07
  • 2022-07-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多