Search code examples
pythonpython-3.xdocstring

How to force help to use overridden __doc__


Let's assume I define a simple class Foo:

class Foo(object):
    """This is Foo"""
    def __init__(self, label):
        self.__doc__ = "This is {} Foo".format(label)

    def __call(self, *args):
        ... # Some behavior which depends on the constructor arguments.

I see that object __doc__ is picked up by ? in IPython:

In [1]: %doctest_mode
Exception reporting mode: Plain
Doctest mode is: ON
>>> some = Foo("some")
>>> ?some
Type:            Foo
String form:     <__main__.Foo object at 0x7f01620a49b0>
Docstring:       This is some Foo
Class docstring: This is Foo

but ignored by help:

>>> help(some)

Help on Foo in module __main__ object:

class Foo(builtins.object)
 |  This is Foo
 |  
 |  Methods defined here:
 |  
 |  __init__(self, label)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)
(END)

Is it possible to influence help behavior without modifying Class docstring? I would like to Class docstring to be ignored when working with instances.


Solution

  • First: I wouldn't recommend it! If you seriously change the logic depending on the arguments, you are probably better of using a factory function and several distinct (sub-)classes.

    After having said that: it's possible. One way would be using dynamic types and subclassing. However you need to use __new__ instead of __init__:

    class Foo(object):
        """This is Foo"""
        def __new__(cls, label):
            newcls = type('FooSubclass', (Foo, ), {'__doc__': "This is {} Foo".format(label)})
            return newcls
    
    >>> help(Foo('a'))
    Help on class FooSubclass in module __main__:
    
    class FooSubclass(Foo)
     |  This is a Foo
     |  
     |  Method resolution order:
     |      FooSubclass
     |      Foo
     |      __builtin__.object
     |  
     |  Static methods inherited from Foo:
     |  
     |  __new__(cls, label)
     |  
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from Foo:
     |  
     |  __dict__
     |      dictionary for instance variables (if defined)
     |  
     |  __weakref__
     |      list of weak references to the object (if defined)