amirdel
amirdel

Reputation: 53

How can you pass a docstring to a wrapper function in python?

If I have a class that is wrapping another object (let's say Pandas dataframe), how can I pass the docstrings from the wrapped class to the wrapper class?

For example, in the code below:

import pandas as pd

class DataframeWrapper():
    def __init__(self, df):
        self.df = df

    def plot(self, *args, **kwargs):
        self.df.plot(*args, **kwargs)

df1 = pd.DataFrame(data=np.random.normal(0,1, size=(10,2)), columns=['a', 'b'])
wdf1 = DataframeWrapper(df1)
wdf1.plot('a', 'b')

How can I get the plot function in the wrapper class to have the same docstring as Pandas plot (so that it can be seen in Jupyter by pressing shift+tab)?

Upvotes: 2

Views: 1575

Answers (1)

Todd
Todd

Reputation: 5395

Alright.. putting this here so you can see the hackish idea I had.. it seems to work, but don't know if it's all that pretty... here it is...

>>> class DataframeWrapper():
...     def __init__(self, df):
...         self.df = df
...         
...         @functools.wraps(df.plot)
...         def _plot(*args, **kwargs):
...             return df.plot(*args, **kwargs)
...             
...         self.plot = _plot

Trying it out in my shell, a huge doc string box fills my screen.. This is about as good as a method declared the other way.. you have access to self within it as well as the hosted dataframe.

This basically does the same thing a decorator does. You could just declare functions for each dataframe method you're interested in and assign them to attributes within __init__().

Taking it a step further we could create a decorator style function.

>>> def dfwrap(method):
...     @functools.wraps(method)
...     def _dfwrap(*args, **kwargs):
...         # Do some extra stuff here...
...         return method(*args, **kwargs)
...     return _dfwrap

Then in __init__():

...     self.foo = dfwrap(df.foo)
...     self.bar = dfwrap(df.bar)
...     self.baz = dfwrap(df.baz)

Upvotes: 2

Related Questions