2

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)?

7
  • you can access the doc string using the __doc__ property on objects. They are writable. Commented Apr 15, 2020 at 21:14
  • how can I assign that doc to the wrapper function's plot method? Commented Apr 15, 2020 at 22:29
  • self.plot.__doc__ = df.plot.__doc__ Commented Apr 15, 2020 at 22:59
  • That gives me an error: AttributeError: attribute '__doc__' of 'method' objects is not writable. I am adding this line to the end of the constructor. Commented Apr 16, 2020 at 3:48
  • hmm.. lemme try this.. Commented Apr 16, 2020 at 4:24

1 Answer 1

2

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)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.