相当于Python中字段的NotImplementedError

2024-06-25 06:13:01 发布

您现在位置:Python中文网/ 问答频道 /正文

在Python2.x中,如果要将方法标记为抽象方法,可以这样定义:

class Base:
    def foo(self):
        raise NotImplementedError("Subclasses should implement this!")

如果忘记覆盖它,就会得到一个很好的提醒异常。有没有一种等效的方法将字段标记为抽象字段?或者你只能在类docstring中声明它吗?

一开始我以为我可以将字段设置为NotImplemented,但当我查找它的实际用途(丰富的比较)时,它似乎是滥用的。


Tags: 方法标记selfbase定义foodefimplement
3条回答

是的,你可以。使用@property装饰器。例如,如果有一个名为“example”的字段,则不能执行以下操作:

class Base(object):

    @property
    def example(self):
        raise NotImplementedError("Subclasses should implement this!")

运行下面的命令会生成一个NotImplementedError就像您想要的那样。

b = Base()
print b.example

备选答案:

@property
def NotImplementedField(self):
    raise NotImplementedError

class a(object):
    x = NotImplementedField

class b(a):
    # x = 5
    pass

b().x
a().x

这与Evan类似,但简洁且便宜——您只会得到一个NotImplementedField实例。

更好的方法是使用Abstract Base Classes

import abc

class Foo(abc.ABC):

    @property
    @abc.abstractmethod
    def demo_attribute(self):
        raise NotImplementedError

    @abc.abstractmethod
    def demo_method(self):
        raise NotImplementedError

class BadBar(Foo):
    pass

class GoodBar(Foo):

    demo_attribute = 'yes'

    def demo_method(self):
        return self.demo_attribute

bad_bar = BadBar()
# TypeError: Can't instantiate abstract class BadBar \
# with abstract methods demo_attribute, demo_method

good_bar = GoodBar()
# OK

请注意,您应该仍然拥有raise NotImplementedError,而不是pass,因为没有任何东西阻止继承类调用super().demo_method(),如果抽象demo_method只是pass,那么这将无声地失败。

相关问题 更多 >