2
\$\begingroup\$

I'm adding/editing the docstrings to my custom tkinter modules. These contain classes that are subclassing tkinter objects as well as each other. I'm trying to follow PEP 257, but applying to this case feels forced and awkward. Any criticism of how I'm going about this is welcome, but these items in particular concern me:

  1. A subclass init often feels like it doesn't need a docstring.
  2. I'm not sure that it's necessary to list parent and kwargs in an init docstring, if they're just being passed to the parent's init method.
  3. If I have a dozen subclasses of the same custom object (here, ToolBar), the documentation will be repetitive. If someone might be importing just one of the subclasses, then its documentation should be complete, but I don't anticipate that use case for my project's code.

Example:

# toolbars.py
"""Custom tkinter frames that hold multiple widgets plus capabilities to
store data and send it to a controller.

Provides the following classes:
* ToolBar: A base class for creating toolbars, intended to be subclassed and
extended.

* AB_Bar, AB2_Bar, ABX_Bar, ABX3_Bar, AAXX_Bar, AABB_Bar: hold numerical inputs
required for simulating AB, AB2, ABX, ABX3, AA'XX', and AA'BB' spin systems.

* FirstOrderBar: holds numerical inputs required for first-order simulation

* SecondOrderBar: holds numerical inputs, plus a button with a pop-up 2D
array for entering chemical shifts and J coupling constants, for second-order
simulations of up to 8 coupled spins.

* DNMR_TwoSingletBar: holds "custom SpinBox" numerical inputs for the
simulation of a DNMR lineshape for two uncoupled spins.

* DNMR_AB: holds "custom spinbox" numerical inputs for the simulation of a
DNMR lineshape for two coupled spins (AB quartet at the slow exchange limit).
"""

from tkinter import *  # wildcard imports are bad, but common for tkinter  

import numpy as np

from myproject.GUI.widgets import (ArrayBox, ArraySpinBox, VarBox, IntBox,
                                   VarButtonBox)
from myproject.initialize import getWINDNMRdefault


class ToolBar(Frame):
    """
    Extend tkinter.Frame with a dictionary, a controller reference, a model
    name, and a function to call the appropriate model.

    Intended to be subclassed, and not instantiated itself.

    methods:
        request_plot: sends model type and data to the controller

    Attributes:
        controller: the Controller object of the Model-View-Controller
        architecture. Assumes controller has an update_view_plot method.
        model (str): the type of calculation requested (interpreted by the
        controller).
        vars (dict): holds the kwargs that the controller is called with.
        Intent is that child widgets will store and update their data to this
        dict.
    """

    def __init__(self, parent=None, controller=None, **options):
        """Initialize the ToolBar object with a reference to a controller.

        Keyword arguments:
        :param parent: the parent tkinter object
        :param controller: the Controller object of the MVC application
        :param options: standard optional kwargs for a tkinter Frame
        """
        Frame.__init__(self, parent, **options)
        self.controller = controller
        self.model = 'model'  # must be overwritten by subclasses
        self.vars = {}

    def request_plot(self):
        """Send request to controller to recalculate and refresh the view's
        plot.
        """
        self.controller.update_view_plot(self.model, **self.vars)


class AB_Bar(ToolBar):
    """
    A subclass of ToolBar designed for use with AB simulations.

    Extends ToolBar with AB quartet inputs, and overwrites .model as 'AB'.
    """
    def __init__(self, parent=None, **options):
        ToolBar.__init__(self, parent, **options)
        self.model = 'AB'
        Jab = VarBox(self, name='Jab', default=12.00)
        Vab = VarBox(self, name='Vab', default=15.00)
        Vcentr = VarBox(self, name='Vcentr', default=150)
        Jab.pack(side=LEFT)
        Vab.pack(side=LEFT)
        Vcentr.pack(side=LEFT)
        # initialize self.vars with toolbox defaults
        for child in self.winfo_children():
            child.to_dict()


class AB2_Bar(ToolBar):
    """
    A subclass of ToolBar designed for use with AB2 simulations.

    Extends ToolBar with necessary AB2 inputs, and overwrites .model as 'AB2'.
    """
    def __init__(self, parent=None, **options):
        ToolBar.__init__(self, parent, **options)
        self.model = 'AB2'
        Jab = VarBox(self, name='Jab',    default=12.00)
        Vab = VarBox(self, name='Vab',    default=15.00)
        Vcentr = VarBox(self, name='Vcentr', default=150)
        Jab.pack(side=LEFT)
        Vab.pack(side=LEFT)
        Vcentr.pack(side=LEFT)
        # initialize self.vars with toolbox defaults
        for child in self.winfo_children():
            child.to_dict()

# Many other classes omitted
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.