相当于 Python 中字段的 NotImplementedError
在Python 2.x中,当你想将一个方法标记为抽象时,你可以像这样定义它:
class Base:
def foo(self):
raise NotImplementedError("Subclasses should implement this!")
然后,如果你忘记重写它,你会得到一个很好的提醒异常。 是否有等效的方法将字段标记为抽象? 或者你能做的就是在类文档字符串中声明它吗?
起初我以为我可以将该字段设置为 NotImplemented,但当我查找它的实际用途(丰富的比较)时,它似乎很滥用。
In Python 2.x when you want to mark a method as abstract, you can define it like so:
class Base:
def foo(self):
raise NotImplementedError("Subclasses should implement this!")
Then if you forget to override it, you get a nice reminder exception. Is there an equivalent way to mark a field as abstract? Or is stating it in the class docstring all you can do?
At first I thought I could set the field to NotImplemented, but when I looked up what it's actually for (rich comparisons) it seemed abusive.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
是的你可以。 使用@property装饰器。 例如,如果您有一个名为“example”的字段,那么您不能执行以下操作:
运行以下命令会产生
NotImplementedError
就像您想要的那样。Yes, you can. Use the
@property
decorator. For instance, if you have a field called "example" then can't you do something like this:Running the following produces a
NotImplementedError
just like you want.替代答案:
这就像 Evan 的,但简洁且便宜 - 您只会获得 NotImplementedField 的单个实例。
Alternate answer:
This is like Evan's, but concise and cheap--you'll only get a single instance of NotImplementedField.
更好的方法是使用 抽象基类:
请注意,您仍然应该使用
raise NotImplementedError
而不是pass
之类的东西,因为没有什么可以阻止继承类调用super().demo_method()
,并且如果抽象的demo_method
只是pass
,这会默默地失败。A better way to do this is using Abstract Base Classes:
Note that you should still have
raise NotImplementedError
instead of something likepass
, because there is nothing preventing the inheriting class from callingsuper().demo_method()
, and if the abstractdemo_method
is justpass
, this will fail silently.请注意将类类型传递到
require_abstract_fields
中,因此如果多个继承类使用此类型,它们不会全部验证最派生类的字段。 您也许可以使用元类自动执行此操作,但我没有深入研究这一点。 接受将字段定义为“无”。Note the passing of the class type into
require_abstract_fields
, so if multiple inherited classes use this, they don't all validate the most-derived-class's fields. You might be able to automate this with a metaclass, but I didn't dig into that. Defining a field to None is accepted.看来这个问题对实例属性和类属性都是开放的,我将只关注第一个主题。
因此,对于属性来说,Evan 的替代答案是使用
pyfields
:产量
当然,它不为您提供通过对话编辑错误消息的能力关于子类。 但在某种程度上,不谈论子类更为现实——事实上,在Python中,属性可以在基类的实例上被覆盖——而不仅仅是在子类中。
注意:我是 pyfields 的作者。 有关详细信息,请参阅文档。
It seem that this question was open to both instance attributes and class attributes, I'll focus on the first topic only.
So, for instance attributes, an alternate answer to Evan's is to define a mandatory field using
pyfields
:yields
Granted, it does not provide you with the ability to edit the error message by talking about subclasses. But in a way it is more realistic to not talk about subclasses - indeed in python, attributes can be overridden on instances of the base class - not only in subclasses.
Note: I'm the author of
pyfields
. See documentation for details.下面是一个如何在 Python 3 中为子类设置所需属性/方法的简单示例。
Here is a simple example how to set required properties/methods for sublasses in Python 3.
这是我的解决方案:
它可以用作
And here is my solution:
It can be used as
处理此问题的一个有趣模式是在父类中将属性设置为 None ,并使用确保已在子类中设置该属性的函数来访问该属性。
这是 django-rest-framework 的示例:
An interesting pattern to handle this is to set attribute to
None
in the parent class and to access the attribute with a function that ensure it has been set in the child class.Here is an example from django-rest-framework: