在抽象方法的主体中应该放置什么内容?

8 浏览
0 Comments

在抽象方法的主体中应该放置什么内容?

假设我有以下抽象类Foo

import abc
class Foo(abc.ABC):
    @abc.abstractmethod
    def bar(self):
        raise NotImplementedError

bar方法的主体中应该放什么?

我看到很多代码都写了raise NotImplementedError,就像上面展示的那样。然而,这似乎是多余的,因为任何没有实现bar的子类在实例化时都会引发TypeError: Can't instantiate abstract class Foo with abstract methods bar

bar留空,像下面这样,符合Python的风格吗?

import abc
class Foo(abc.ABC):
    @abc.abstractmethod
    def bar(self):
        ...

这是Python文档中关于抽象基类的写法,但我不确定这是否只是一个占位符还是实际的代码示例。

如果将bar只写三个点(...),这样做是否可以?那么何时应该使用NotImplementedError

0
0 Comments

在这段内容中,问题的原因是作者询问应该在抽象方法的主体中放置什么。解决方法是通过提供默认实现来允许子类调用super(),并提供了一个示例代码来说明这一点。此外,还提到了collections.abc类的源代码中的示例。还提到了链接中的MutableSet.add和MutableSet.discard方法会引发NotImplementedError异常。

以下是整理后的文章:

文档的目的是为您提供一个示例,您不必遵循这个示例。您可以提供一个默认实现;子类仍然可以使用super()来调用您的实现。这就是大多数collections.abc类所做的事情;请参阅源代码。

例如,Size类的__len__方法返回0:

class Sized(metaclass=ABCMeta):
    # ...
    def __len__(self):
        return 0

感谢提供的链接。MutableSet.add和MutableSet.discard确实会引发NotImplementedError异常,所以我猜我应该坚持这种约定,而不是使用...。

根据上述内容,问题的原因是作者不清楚在抽象方法的主体中应该放置什么。解决方法是提供一个默认实现,并允许子类调用super()来调用该实现。此外,还提供了一个示例代码来说明这一点,并提到了collections.abc类的源代码中的示例。还提到了链接中的MutableSet.add和MutableSet.discard方法会引发NotImplementedError异常。

0
0 Comments

在Python中,抽象方法是一种没有具体实现的方法,它只是一个接口,用于指示派生类必须实现该方法。当定义一个抽象方法时,通常会面临一个问题:在抽象方法的主体中应该放什么?

按照Martijn Pieters的说法,可以在适当的地方提供一个默认值。这意味着如果派生类没有实现该方法,那么将使用默认值。下面是一个示例:

class FooBar(abc.ABC):
    def foo(bar):
        """This method foos some bars"""
        raise NotImplementedError

在这个示例中,如果派生类没有实现`foo`方法,那么当调用该方法时,将会引发`NotImplementedError`异常。这是一种明确告诉用户必须覆盖该方法的方法。

根据Python官方文档的建议,还有一些其他的方法可以在抽象方法的主体中使用,包括:

1. 使用省略号(`...`)代替`raise NotImplementedError`。这种方法在官方的Python文档中的抽象基类的示例中有支持。

2. 只使用`pass`语句。这种方法也很常见,它表示不做任何操作。

3. 实际上,只使用文档字符串是足够的。因为任何方法都应该有文档字符串,所以这种方法比使用省略号或`pass`语句更加优雅。

有多种方法可以在抽象方法的主体中使用。选择合适的方法取决于具体的需求和个人的偏好。无论选择哪种方法,都应该明确地告诉用户该方法是抽象的,需要在派生类中进行实现。

0