Welcome, guest | Sign In | My Account | Store | Cart

My first recipe here, it uses __getattr__ to modify the error messages given when a wrong class method is called. It shows the first five ranked most similar method names, followed by the first line of their docstrings (this is useful to see their parameters, if you use this convention in your sources), and then it raises an AttributeError. Useful from the interactive shell too.

Python, 36 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from difflib import get_close_matches # for __getattr__

class Demo(object):
    def __getattr__(self, name):
        """If a wrong method is called, this suggests methods with similar names."""
        toRemove = """__delattr__ __dict__ __getattribute__ __module__ __new__
                      __reduce__ __copy__ __reduce_ex__ __setattr__ __slot__
                      __weakref__ __str__ __class__ __doc__""".split()
        methods = set(dir(self.__class__)).difference(toRemove)
        suggestions = get_close_matches(name.lower(), methods, 5)
        raise_comment = "method '%s' not found.\n" % name
        raise_comment += "Most similar named ones: %s\n\n" % ", ".join(suggestions)
        first_lines = []
        for method in suggestions:
            doc = getattr(self.__class__, method).__doc__
            if doc:
                first_lines.append(doc.splitlines()[0])
            else:
                first_lines.append(method + " - no docstring found.")
        raise AttributeError, raise_comment + "\n".join(first_lines)

    # Some useless methods for this demo
    def addcube(self):
        """docstring of addcube()"""
    def addrube(self):
        """docstring of addrube()"""
    def adder(self):
        """docstring of adder()"""
    def waiter(self):
        """docstring of waiter()"""
    def boiler(self):
        """docstring of boiler()"""

# Test of the __getattr__
d = Demo()
d.addCube()

This smart error message idea comes a bit from the Mathematica textual interface.

For classes with many methods (like a Graph object), the "smart help" idea can be extended with a method working as a little search engine that suggests what method can be used, based on a textual description of what the user wants to do with/to the object. Such search engine can index the the docstrings text, and maybe a list of keywords added to each docstring.

V.1.1: a fix for methods without docstring. V.1.2: now I know more Python, so I've cleaned this script, improved it, and added a small demostration.

1 comment

s_h_a_i_o 10 years, 3 months ago  # | flag

Is it possible to add the Demo behaviour to an existing class using decorator ? It would be easier to remove the Demo Inheritance once the code is definitive.

Created by bearophile - on Wed, 6 Apr 2005 (PSF)
Python recipes (4591)
bearophile -'s recipes (15)

Required Modules

Other Information and Tasks