哪个异常用于通知子类应实现方法?

12 投票
3 回答
4857 浏览
提问于 2025-04-16 02:44

假设我想在Python中创建一个抽象类,这个类里面有一些方法需要子类来实现,比如:

class Base():
    def f(self):
        print "Hello."
        self.g()
        print "Bye!" 

class A(Base):
    def g(self):
        print "I am A"

class B(Base):
    def g(self):
        print "I am B"

我希望如果直接使用这个基类并调用它的 f() 方法时,当调用 self.g() 方法时,会抛出一个异常,提示你子类应该实现 g() 方法。

在这种情况下,通常应该怎么做呢?我应该抛出一个 NotImplementedError?,还是有其他更合适的方法呢?

3 个回答

0

彼得·诺维格在他的Python《不常被问的问题》列表中提供了一个解决方案。我在这里把它复制过来。你可以去看看这个列表,它非常有用。

## Python
class MyAbstractClass:
    def method1(self): abstract

class MyClass(MyAbstractClass): 
    pass

def abstract():
    import inspect
    caller = inspect.getouterframes(inspect.currentframe())[1][3]
    raise NotImplementedError(caller + ' must be implemented in subclass')
2

创建一个什么都不做的方法,但要写一个说明文档来解释这个方法的用法。出现NameError会让人感到困惑,而抛出NotImplementedError(或者其他任何错误)会影响super的正常使用。

15

在Python 2.6及更高版本中,你可以使用abc模块来让Base成为一个“真正的”抽象基类:

import abc

class Base:
    __metaclass__ = abc.ABCMeta
    @abc.abstractmethod
    def g(self):
        pass
    def f(self): # &c

这样可以确保Base不能被实例化,也就是说不能直接创建Base的对象。同时,如果子类没有重写g方法,它们也不能被实例化。这种做法满足了@Aaron的要求,让子类可以在自己的g实现中使用super。总的来说,这比我们在Python 2.5及更早版本中使用的方案要好得多!

顺便提一下,让Base继承自object是多余的,因为元类需要明确设置。

撰写回答