__peter__ at web
Jun 24, 2012, 1:07 AM
Post #2 of 9
Josh English wrote:
> I'm creating a cmd.Cmd class, and I have developed a helper method to
> easily handle help_xxx methods.
> I'm trying to figure out if there is an even lazier way I could do this
> with decorators.
> Here is the code:
> import cmd
> def add_help(func):
> if not hasattr(func, 'im_class'):
> return func #probably should raise an error
> cls = func.im_class
> setattr(cls, func.im_func.__name__.replace("do","help"), None)
> return func
> class BaseCmd(cmd.Cmd):
> def __init__(self, *args, **kwargs):
> cmd.Cmd.__init__(self, *args, **kwargs)
> def show_help(self, func):
> print "\n".join((line.strip() for line in
> def do_done(self, line):
> Quits this and goes to higher level or quits the application.
> I mean, what else do you expect?
> return True
> if __name__=='__main__':
> c = BaseCmd()
> print c.help_done
> This generates "AttributeError: BaseCmd instance has no attribute
> The show_help method is the shortcut I want to use (I'm pretty sure it's
> from Doug Hellman's site). I'm wondering if it's possible to use a
> decorator such as add_help to automatically create the appropriate
> help_xxx function.
> In the decorator, I can get the function and the name of the class, but I
> can't find the instance of the class that the method is attached to.
> Maybe this is just one step of lazy too far.
> Am I right in thinking that I can't do this? There is no way to access the
> class instance from the method?
You cannot access a class instance because even the class itself doesn't
exist yet. You could get hold of the class namespace with sys._getframe(),
f = getattr(self, %r)
""" % (f.__name__[3:], f.__name__) in sys._getframe(1).f_locals
but here's a simpler approach:
f.help = help
def __init__(self, *args, **kwargs):
cmd.Cmd.__init__(self, *args, **kwargs)
def show_help(self, func):
print "\n".join((line.strip() for line in
def __getattr__(self, name):
helpfunc = getattr(self, "do_" + name[5:]).help
setattr(self.__class__, name, helpfunc)
return getattr(self, name)
def do_done(self, line):
Quits this and goes to higher level or quits the application.
I mean, what else do you expect?
c = BaseCmd()