我有两个数据结构Frontier
(一个队列)和Explored
(一组)。我想实现他们共享的自定义__contains__
方法:
class Custom_Structure:
def __contains__(self, item):
# TODO
class Frontier(Custom_Structure):
def __init__(self):
self.queue = Queue.Queue()
class Explored(Custom_Structure):
def __init__(self):
self.set = set()
我理解继承和抽象类的理论(或者至少,我认为我做了!)。似乎在这里使Custom_Structure
成为一个抽象类是合适的,因为我不打算将它实例化;只有Frontier
和Explored
才能共享__contains__
方法。我不需要任何抽象方法,但这没关系,因为我已经读过抽象类不一定需要抽象方法。
如果我在C#中这样做,我只需添加abstract
关键字,我就不会问这个问题了。但在Python(2.7)中,似乎我需要做这样的事情:
from abc import ABCMeta
class Custom_Structure:
__metaclass__ = ABCMeta
...
好吧,它仍然没有那么大的优惠,但它的可读性不是很高,只是感觉有点过分,并没有多少好处。我很想留下我的代码。
所以我的问题是:为什么要麻烦让Custom_Structure
抽象?(那么如果有人实例化基类呢?)
我已经找到了以下问题,但他们并没有完全回答这个问题:
Why use Abstract Base Classes in Python?这里的答案似乎不适用,因为我没有任何抽象方法,因此基类和子类之间没有契约。
What is the main advantage of making a class abstract相同
Abstract class with no abstract methods这有“防止实例化”的答案,但为什么会出现这样的问题呢?
What's the point in having an abstract class with no abstract methods?相同
Why use an abstract class without abstract methods?同样。我理解为什么不应该实例化它的理论概念,但实际上有什么大不了的呢?
我已经阅读了关于抽象类背后理论的各种问题和答案 - 我的问题不是关于它们是什么以及它们是如何工作的(尽管如果我错了请告诉我),它更多的是“有什么好处”在这个简单的情况下?
答案 0 :(得分:3)
有趣的问题。首先让我说,这个丑陋的事实是在python2中创建抽象类的方式......
from abc import ABCMeta
class Custom_Structure:
__metaclass__ = ABCMeta
...已经表明Python独裁者并不认为将类标记为明确抽象是非常重要的。
也就是说,创建类抽象是向代码添加元数据的有用方法。这是一个类的作者与模块的未来用户进行通信的一种方式。
说什么?两件事:
抽象类不完整,不应该实例化。此类的实例没有具体含义,因为定义是 partial 。它缺乏使对象工作所需的全套信息。
抽象方法是定义的缺失部分。通过将方法抽象化,您可以说明为了使类有意义,必须提供完整描述的这个特定部分。不仅如此,而且通过提供一个界面,您可以传达缺失部分的预期行为,无论内部细节最终如何。
当然,所有这些都可以在实践中没有任何额外的规范用于类或其方法,但是继承者最终会猜测如何使用该对象,或者必须阅读文档详细。
如果实例化隐式抽象类,迟早会发生错误。当某些东西丢失时,最终会产生NotImplementedError
或KeyError
。这个错误很容易实现,并且在尝试使用对象的功能时会出现。
如果您尝试实例化显式抽象类,则错误立即生效。 没有掷骰子,并且不会推迟到以某种方式使用该类时问题。如果使用该方法,抽象方法的缺失实现将不会导致错误,但是在编码错误发生时立即出现错误。
总结一下,使一个类及其一些方法显式抽象,使代码的实际情况符合文档。它将了解规则的责任从无经验的用户转移到作者。 这是一种让语言运行时在实践中强制执行理论规则和使用限制的方法。