I have a container class (subclassed from list) where I have overridden the geattr method;
def __getattr__(self, name):
def _multiplexed(*args, **kwargs):
return [getattr(R, name)(*args, **kwargs) for R in self]
return _multiplexed
The trouble is that now I can’t ask Python for help about my object. When I do ask for help I get (traceback from iPython) the error which is copied below.
So the question is: How can I override getattr without losing my ability to call for help?
Thanks,
Jeremy
help(Collect)
/home/jlconlin/CustomPython/trunk/Collect.py in <module>()
----> 1
2
3
4
5
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site.pyc in __call__(self, *args, **kwds)
455 def __call__(self, *args, **kwds):
456 import pydoc
--> 457 return pydoc.help(*args, **kwds)
458
459 def sethelper():
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pydoc.pyc in __call__(self, request)
1721 def __call__(self, request=None):
1722 if request is not None:
-> 1723 self.help(request)
1724 else:
1725 self.intro()
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pydoc.pyc in help(self, request)
1768 elif request: doc(request, 'Help on %s:')
1769 elif isinstance(request, Helper): self()
-> 1770 else: doc(request, 'Help on %s:')
1771 self.output.write('\n')
1772
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pydoc.pyc in doc(thing, title, forceload)
1506 """Display text documentation, given an object or a path to an object."""
1507 try:
-> 1508 pager(render_doc(thing, title, forceload))
1509 except (ImportError, ErrorDuringImport), value:
1510 print value
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pydoc.pyc in render_doc(thing, title, forceload)
1483 desc = describe(object)
1484 module = inspect.getmodule(object)
-> 1485 if name and '.' in name:
1486 desc += ' in ' + name[:name.rfind('.')]
1487 elif module and module is not object:
TypeError: argument of type 'function' is not iterable
Looking at the pydoc source code, the culprit is:
That tries to look up
thing.__name__, and if it fails, returns None instead. Except, in your case, it doesn’t fail; it gets a value back from__getattr__instead.If you’re overriding
__getattr__, it’s a good idea to special case all special attributes. Something like:This ensures that if your class doesn’t have a particular special attribute (in this case,
__name__), lookups for it will fail, rather than producing an unexpected value.