使用一种方法的文档字符串自动覆盖另一种方法的文档字符串
问题:我有一个类,其中包含一个模板方法 execute
,它调用另一个方法 _execute
。 子类应该覆盖_execute
来实现一些特定的功能。 此功能应记录在 _execute
的文档字符串中。 高级用户可以创建自己的子类来扩展库。 但是,处理此类子类的另一个用户应该只使用 execute
,因此如果他使用 help(execute)
,他将看不到正确的文档字符串。
因此,最好以这样的方式修改基类,以便在子类中 execute
的文档字符串自动替换为 _execute
的文档字符串。 有什么想法可以做到这一点吗?
我正在考虑使用元类来做到这一点,使这对用户完全透明。
The problem: I have a class which contains a template method execute
which calls another method _execute
. Subclasses are supposed to overwrite _execute
to implement some specific functionality. This functionality should be documented in the docstring of _execute
.
Advanced users can create their own subclasses to extend the library. However, another user dealing with such a subclass should only use execute
, so he won't see the correct docstring if he uses help(execute)
.
Therefore it would be nice to modify the base class in such a way that in a subclass the docstring of execute
is automatically replaced with that of _execute
. Any ideas how this might be done?
I was thinking of metaclasses to do this, to make this completely transparent to the user.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
好吧,如果您不介意在子类中复制原始方法,则可以使用以下技术。
Well, if you don't mind copying the original method in the subclass, you can use the following technique.
是否有原因无法直接重写基类的
execute
函数?如果您不想执行上述操作:
方法对象不支持写入
__doc__
属性,因此您必须在实际函数对象中更改__doc__
。 由于您不想覆盖基类中的副本,因此您必须为每个子类提供自己的execute
副本:但这类似于重新定义
execute 的一种迂回方式
...Is there a reason you can't override the base class's
execute
function directly?If you don't want to do the above:
Method objects don't support writing to the
__doc__
attribute, so you have to change__doc__
in the actual function object. Since you don't want to override the one in the base class, you'd have to give each subclass its own copy ofexecute
:but this is similar to a roundabout way of redefining
execute
...看一下 functools.wraps() 装饰器; 它完成了所有这些,但我不知道是否可以让它在正确的上下文中运行
Look at the functools.wraps() decorator; it does all of this, but I don't know offhand if you can get it to run in the right context
那么文档字符串存储在
__doc__
中,因此事后根据_execute
的文档字符串重新分配它不会太难。基本上:
必须重新声明执行,以便将文档字符串附加到
SubClass
而不是的执行版本>MyClass
(否则会干扰其他子类)。这不是一种非常简洁的方法,但从库用户的角度来看,它应该给出所需的结果。 然后,您可以将其包装在元类中,以方便进行子类化的人。
Well the doc-string is stored in
__doc__
so it wouldn't be too hard to re-assign it based on the doc-string of_execute
after the fact.Basically:
Execute has to be re-declared to that the doc string gets attached to the version of execute for the
SubClass
and not forMyClass
(which would otherwise interfere with other sub-classes).That's not a very tidy way of doing it, but from the POV of the user of a library it should give the desired result. You could then wrap this up in a meta-class to make it easier for people who are sub-classing.
我同意,解决此问题的最简单、最 Python 的方法是在子类中简单地重新定义执行并让它调用基类的执行方法:
这是完成您想要的任务的很少的代码; 唯一的缺点是您必须在扩展 Base 的每个子类中重复此代码。 然而,这对于你想要的行为来说只是一个很小的代价。
如果您想要一种草率且冗长的方式来确保动态生成执行的文档字符串,您可以使用描述符协议,这将比此处的其他建议少得多的代码。 这很烦人,因为您不能只在现有函数上设置描述符,这意味着必须使用
__call__
方法将执行编写为单独的类。下面是执行此操作的代码,但请记住,我上面的示例要简单得多,也更 Pythonic:
I agree that the simplest, most Pythonic way of approaching this is to simply redefine execute in your subclasses and have it call the execute method of the base class:
This is very little code to accomplish what you want; the only downside is that you must repeat this code in every subclass that extends Base. However, this is a small price to pay for the behavior you want.
If you want a sloppy and verbose way of making sure that the docstring for execute is dynamically generated, you can use the descriptor protocol, which would be significantly less code than the other proposals here. This is annoying because you can't just set a descriptor on an existing function, which means that execute must be written as a separate class with a
__call__
method.Here's the code to do this, but keep in mind that my above example is much simpler and more Pythonic: