Python中字段的NotImplementedError等价

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

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

那么如果你忘记重写它,你会得到一个很好的提醒exception。 有没有一种等同的方式来标记一个领域是抽象的? 或者在class级文档中说明所有你能做的事情?

起初我以为我可以把这个字段设置为NotImplemented,但是当我查找它的实际内容(比较富有)时,它似乎是一种滥用。

是的你可以。 使用@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 

这就像埃文的,但简洁而又便宜 – 你只会得到一个NotImplementedField的实例。

 def require_abstract_fields(obj, cls): abstract_fields = getattr(cls, "abstract_fields", None) if abstract_fields is None: return for field in abstract_fields: if not hasattr(obj, field): raise RuntimeError, "object %s failed to define %s" % (obj, field) class a(object): abstract_fields = ("x", ) def __init__(self): require_abstract_fields(self, a) class b(a): abstract_fields = ("y", ) x = 5 def __init__(self): require_abstract_fields(self, b) super(b, self).__init__() b() a() 

请注意将类types传递到require_abstract_fields ,所以如果多个inheritance类使用这个类,它们不会全部validation最派生类的字段。 你也许可以用元类自动化这个,但是我没有深入。 定义一个字段为None被接受。

这是我的解决scheme:

 def not_implemented_method(func): from functools import wraps from inspect import getargspec, formatargspec @wraps(func) def wrapper(self, *args, **kwargs): c = self.__class__.__name__ m = func.__name__ a = formatargspec(*getargspec(func)) raise NotImplementedError('\'%s\' object does not implement the method \'%s%s\'' % (c, m, a)) return wrapper def not_implemented_property(func): from functools import wraps from inspect import getargspec, formatargspec @wraps(func) def wrapper(self, *args, **kwargs): c = self.__class__.__name__ m = func.__name__ raise NotImplementedError('\'%s\' object does not implement the property \'%s\'' % (c, m)) return property(wrapper, wrapper, wrapper) 

它可以用作

 class AbstractBase(object): @not_implemented_method def test(self): pass @not_implemented_property def value(self): pass class Implementation(AbstractBase): value = None def __init__(self): self.value = 42 def test(self): return True 

更好的方法是使用抽象基类 :

 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的东西,因为没有什么能够阻止inheritance类调用super().demo_method() ,并且如果抽象的demo_method只是pass ,这将会失败。