Python中字段的NotImplementedError等价物
在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