Python中的抽象方法

dea*_*mon 21 python oop abstract-class python-3.x

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

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
Run Code Online (Sandbox Code Playgroud)

为了引发NotImplementedError,定义"抽象"方法实际上是否有用?

对于抽象方法使用下划线是否是好的风格,那将是protected其他语言?

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

Sve*_*ach 37

在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
Run Code Online (Sandbox Code Playgroud)

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

  • `class Abstract(metaclass = ABCMeta)`只适用于Python 3,对吗? (3认同)

Tri*_*ych 6

如果有疑问,就像Guido那样做.

没有下划线.只需将"抽象方法"定义为引发NotImplementedError的单行程:

class Abstract():
    def ConcreteMethod(self):
        raise NotImplementedError("error message")
Run Code Online (Sandbox Code Playgroud)

  • 和Guido [从不使用CamelCase作为方法名称](http://www.python.org/dev/peps/pep-0008/):) (8认同)
  • 你为什么要命名一个抽象的方法`Conrete`? (4认同)
  • ...但Guido使用下划线来抽象"受保护"方法;-) (3认同)
  • @Ethan Furman:因为程序员应该实现该名称的方法.抽象类必须始终使用以后使用的名称来命名抽象方法. (2认同)