<p>The problem: I have a class which contains a template method <code>execute</code> which calls another method <code>_execute</code>. Subclasses are supposed to overwrite <code>_execute</code> to implement some specific functionality. This functionality should be documented in the docstring of <code>_execute</code>. 
Advanced users can create their own subclasses to extend the library. However, another user dealing with such a subclass should only use <code>execute</code>, so he won't see the correct docstring if he uses <code>help(execute)</code>.</p>

<p>Therefore it would be nice to modify the base class in such a way that in a subclass the docstring of <code>execute</code> is automatically replaced with that of <code>_execute</code>. Any ideas how this might be done?</p>

<p>I was thinking of metaclasses to do this, to make this completely transparent to the user.</p>

[{'answer_id': 72126, 'author': 'John Montgomery', 'author_id': 5868, 'author_profile': 'https://Stackoverflow.com/users/5868', 'pm_score': 0, 'selected': False, 'text': "<p>Well the doc-string is stored in <code>__doc__</code> so it wouldn't be too hard to re-assign it based on the doc-string of <code>_execute</code> after the fact.</p>\n\n<p>Basically:</p>\n\n<p><code></p>\n\n<pre>\nclass MyClass(object):\n    def execute(self):\n        '''original doc-string'''\n        self._execute()\n\nclass SubClass(MyClass):\n    def _execute(self):\n        '''sub-class doc-string'''\n        pass\n\n    # re-assign doc-string of execute\n    def execute(self,*args,**kw):\n        return MyClass.execute(*args,**kw)\n    execute.__doc__=_execute.__doc__\n\n</pre>\n\n<p></code></p>\n\n<p>Execute has to be re-declared to that the doc string gets attached to the version of execute for the <code>SubClass</code> and not for <code>MyClass</code> (which would otherwise interfere with other sub-classes).</p>\n\n<p>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.</p>\n"}, {'answer_id': 72192, 'author': 'dF.', 'author_id': 3002, 'author_profile': 'https://Stackoverflow.com/users/3002', 'pm_score': 2, 'selected': False, 'text': '<p>Is there a reason you can\'t override the base class\'s <code>execute</code> function directly?</p>\n\n<pre><code>class Base(object):\n    def execute(self):\n        ...\n\nclass Derived(Base):\n    def execute(self):\n        """Docstring for derived class"""\n        Base.execute(self)\n        ...stuff specific to Derived...\n</code></pre>\n\n<p>If you don\'t want to do the above:</p>\n\n<p>Method objects don\'t support writing to the <code>__doc__</code> attribute, so you have to change <code>__doc__</code> 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 of <code>execute</code>:</p>\n\n<pre><code>class Derived(Base):\n    def execute(self):\n        return Base.execute(self)\n\n    class _execute(self):\n        """Docstring for subclass"""\n        ...\n\n    execute.__doc__= _execute.__doc__\n</code></pre>\n\n<p>but this is similar to a roundabout way of redefining <code>execute</code>...</p>\n'}, {'answer_id': 72596, 'author': 'Sylvain Defresne', 'author_id': 5353, 'author_profile': 'https://Stackoverflow.com/users/5353', 'pm_score': 3, 'selected': True, 'text': "<p>Well, if you don't mind copying the original method in the subclass, you can use the following technique.</p>\n\n<pre><code>import new\n\ndef copyfunc(func):\n    return new.function(func.func_code, func.func_globals, func.func_name,\n                        func.func_defaults, func.func_closure)\n\nclass Metaclass(type):\n    def __new__(meta, name, bases, attrs):\n        for key in attrs.keys():\n            if key[0] == '_':\n                skey = key[1:]\n                for base in bases:\n                    original = getattr(base, skey, None)\n                    if original is not None:\n                        copy = copyfunc(original)\n                        copy.__doc__ = attrs[key].__doc__\n                        attrs[skey] = copy\n                        break\n        return type.__new__(meta, name, bases, attrs)\n\nclass Class(object):\n    __metaclass__ = Metaclass\n    def execute(self):\n        '''original doc-string'''\n        return self._execute()\n\nclass Subclass(Class):\n    def _execute(self):\n        '''sub-class doc-string'''\n        pass\n</code></pre>\n"}, {'answer_id': 72785, 'author': 'Eli Courtwright', 'author_id': 1694, 'author_profile': 'https://Stackoverflow.com/users/1694', 'pm_score': 0, 'selected': False, 'text': '<p>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:</p>\n\n<pre><code>class Sub(Base):\n    def execute(self):\n        """New docstring goes here"""\n        return Base.execute(self)\n</code></pre>\n\n<p>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.</p>\n\n<p>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 <code>__call__</code> method.</p>\n\n<p>Here\'s the code to do this, but keep in mind that my above example is much simpler and more Pythonic:</p>\n\n<pre><code>class Executor(object):\n    __doc__ = property(lambda self: self.inst._execute.__doc__)\n\n    def __call__(self):\n        return self.inst._execute()\n\nclass Base(object):\n    execute = Executor()\n\nclass Sub(Base):\n    def __init__(self):\n        self.execute.inst = self\n\n    def _execute(self):\n        """Actually does something!"""\n        return "Hello World!"\n\nspam = Sub()\nprint spam.execute.__doc__  # prints "Actually does something!"\nhelp(spam)                  # the execute method says "Actually does something!"\n</code></pre>\n'}, {'answer_id': 73473, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 1, 'selected': False, 'text': "<p>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</p>\n"}]
['https://Stackoverflow.com/questions/71817', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/11992/']