Search code examples
pythonpython-3.xdocstring

Python programmatically set dynamic custom docstring for each method of the class


I am want to achieve dynamically to call a function and generate me a docstring and to be applied for the class methods i need.

Example is below what i have and what i want to achieve, for each method i have a docstring that starts with triple quotes

Currently have the following

class MyClass(BaseHandler, ABC):
    def initialize(self, *args, **kwargs):
        super(MyClass, self).initialize(*args, **kwargs)
        self.description = 'My Class'

    @authenticated()
    @coroutine
    def get(self):
        """
        <div>Method GET</div>
        <div>Description: retrieve list My Class</div>
        """
        # some code here
        self.write({
            'success': True,
            'data': self.description
        })

    @authenticated()
    @coroutine
    def post(self):
        """
        <div>Method POST</div>
        <div>Description: update item My Class</div>
        """
        # some code here
        self.write({
            'success': True,
            'data': self.description
        })

Inside of each method i have a docstring hardcoded and works fine, but i want to achieve to insert the docstring using a function.

Desired result

def generate_docstring(name, method):
    docstring = """
       <div>Method %s</div>
       <div>Description: retrieve list %s</div>
       """ % (method, name)
    return docstring

class MyClass(BaseHandler, ABC):
    def initialize(self, *args, **kwargs):
        super(MyClass, self).initialize(*args, **kwargs)
        self.description = 'My Class'

    @authenticated()
    @coroutine
    def get(self):
        # but this way does not work
        self.generate_docstring(name=self.description, staticmethod='GET')
        
        # some code here
        self.write({
            'success': True,
            'data': self.description
        })

    @authenticated()
    @coroutine
    def post(self):
        # but this way does not work
        self.generate_docstring(name=self.description, staticmethod='POST')
        
        # some code here
        self.write({
            'success': True,
            'data': self.description
        })

There is any way to use a function and call under each method and generate the docstring?

Thanking you in advance


Solution

  • You could use a decorator, though I feel like there's a simpler way to do this.

    def generate_docstring(name, method, action):
        def inner(obj):
            obj.__doc__ = """
                <div>Method {method}</div>
                <div>Description: {action} {name}</div>
                """.format(name=name, method=method, action=action)
            return obj
        return inner
    
    class MyClass:
        description = 'My Class'
    
        @generate_docstring(description, 'GET', 'retrieve list')
        def get(self):
            pass
    
        @generate_docstring(description, 'POST', 'update item')
        def post(self):
            pass
    

    Afterwards, help(MyClass) says:

    class MyClass(builtins.object)
     |  Methods defined here:
     |  
     |  get(self)
     |      <div>Method GET</div>
     |      <div>Description: retrieve list My Class</div>
     |  
     |  post(self)
     |      <div>Method POST</div>
     |      <div>Description: update item My Class</div>
    
    ...