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 > func.__doc__.splitlines())) > > @add_help > def do_done(self, line): > """done > 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 > 'help_done'" > > 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(), def add_help(f): exec """\ def help_%s(self): f = getattr(self, %r) self.show_help(f) """ % (f.__name__[3:], f.__name__) in sys._getframe(1).f_locals return f but here's a simpler approach: import cmd def add_help(f): def help(self): self.show_help(f) f.help = help return f 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 func.__doc__.splitlines())) def __getattr__(self, name): if name.startswith("help_"): helpfunc = getattr(self, "do_" + name[5:]).help setattr(self.__class__, name, helpfunc) return getattr(self, name) raise AttributeError @add_help def do_done(self, line): """done 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() c.cmdloop() -- http://mail.python.org/mailman/listinfo/python-list