Python中字段的NotImplementedError等价物

59 投票
8 回答
45430 浏览
提问于 2025-04-15 13:00

在Python 2.x中,如果你想把一个方法标记为抽象方法,可以这样定义:

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

这样,如果你忘记去重写这个方法,程序会给你一个友好的提醒,抛出一个异常。那么,有没有类似的方法可以把一个字段标记为抽象呢?还是说在类的文档字符串中说明一下就可以了?

一开始我以为可以把这个字段设置为NotImplemented,但当我查了一下它的实际用途(主要是用于丰富的比较操作)后,觉得这样做不太合适。

8 个回答

7

更好的做法是使用抽象基类

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,那么这个调用会悄无声息地失败。

36

另一种答案:

@property
def NotImplementedField(self):
    raise NotImplementedError

class a(object):
    x = NotImplementedField

class b(a):
    # x = 5
    pass

b().x
a().x

这个方法和Evan的类似,但更简洁也更省资源——你只会得到一个NotImplementedField的实例。

61

是的,你可以这么做。使用 @property 装饰器。例如,如果你有一个叫“example”的字段,你就可以这样做:

class Base(object):

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

运行下面的代码会产生一个 NotImplementedError,正是你想要的效果。

b = Base()
print b.example

撰写回答