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.
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.
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.