Python中的抽象方法

时间:2011-05-02 12:11:10

标签: python oop python-3.x abstract-class

我需要像Python(3.2)中的abstract protected方法:

class Abstract:
    def use_concrete_implementation(self):
        print(self._concrete_method())

    def _concrete_method(self):
        raise NotImplementedError()


class Concrete(Abstract):
    def _concrete_method(self):
        return 2 * 3

定义“抽象”方法实际上仅用于引发NotImplementedError吗?

在抽象方法中使用下划线是不错的风格,在其他语言中使用protected

抽象基类(abc)会改进吗?

3 个答案:

答案 0 :(得分:35)

在Python中,通常总是避免使用这些抽象方法。您可以通过文档定义接口,并简单地假设传递的对象满足该接口(“duck typing”)。

如果您真的想用抽象方法定义抽象基类,可以使用abc模块完成:

from abc import ABCMeta, abstractmethod

class Abstract(metaclass=ABCMeta):
    def use_concrete_implementation(self):
        print(self._concrete_method())

    @abstractmethod
    def _concrete_method(self):
        pass

class Concrete(Abstract):
    def _concrete_method(self):
        return 2 * 3

同样,这不是通常的Python做事方式。 abc模块的主要目标之一是引入一种重载isinstance()的机制,但通常会避免isinstance()检查以支持鸭子输入。如果需要,请使用它,但不能用作定义接口的一般模式。

答案 1 :(得分:5)

如有疑问,do as Guido does.

没有下划线。只需将“抽象方法”定义为引发NotImplementedError:

的单行程序
class Abstract():
    def ConcreteMethod(self):
        raise NotImplementedError("error message")

答案 2 :(得分:0)

基本上,这里不需要基类中的空方法。就这样做:

class Abstract:
    def use_concrete_implementation(self):
        print(self._concrete_method())

class Concrete(Abstract):
    def _concrete_method(self):
        return 2 * 3

实际上,您通常甚至不需要Python中的基类。由于所有调用都是动态解析的,如果该方法存在,则会调用它,否则将调用AttributeError

注意:在文档中提及需要在子类中实现_concrete_method