Python中的抽象方法

299 投票
6 回答
342811 浏览
提问于 2025-04-16 08:12

我在用Python做继承的时候遇到了一些麻烦。虽然在Java中这个概念对我来说很简单,但到现在为止我还是没能理解Python中的继承,这让我感到有点惊讶。

我有一个原型,代码如下:

class Shape():
   def __init__(self, shape_name):
       self.shape = shape_name

class Rectangle(Shape):
   def __init__(self, name):
       self.shape = name

在上面的代码中,我该如何创建一个抽象方法,让所有的子类都必须实现这个方法呢?

6 个回答

48

你可以查看一下abc模块。简单来说,你在类里定义__metaclass__ = abc.ABCMeta,然后用@abc.abstractmethod装饰每个抽象方法。这样,从这个类派生出来的类就不能被实例化,除非所有的抽象方法都被重写。

如果你的类已经在使用元类,那就把它从ABCMeta派生,而不是type,这样你就可以继续使用你自己的元类。

一个简单的替代方案(在abc模块出现之前的最佳实践)是让所有的抽象方法抛出一个异常(NotImplementedError是个不错的选择),这样从这个类派生的类就必须重写这些方法才能有用。

不过,abc的方案更好,因为它完全阻止了这些类的实例化(也就是说,它“失败得更快”),而且你还可以提供每个方法的默认或基础实现,派生类可以通过super()函数来访问这些实现。

363

在引入abc之前,你经常会看到这个。

class Base(object):
    def go(self):
        raise NotImplementedError("Please Implement this method")


class Specialized(Base):
    def go(self):
        print "Consider me implemented"
330

大概是这样的,使用 ABC

import abc

class Shape(object):
    __metaclass__ = abc.ABCMeta
    
    @abc.abstractmethod
    def method_to_implement(self, input):
        """Method documentation"""
        return
    

另外,看看这个不错的教程: https://pymotw.com/3/abc/

你还可以了解一下 zope.interface,这是在 Python 引入 ABC 之前使用的。

撰写回答