[EMAIL PROTECTED] wrote: > I'm developing a library at the moment that involves many classes, some > of which have "exposed" capabilities. I'm trying to design a nice > interface for both exposing those capabilities, and inspecting > instances to find out what capabilities they have. > > At the moment, I'm leaning towards a superclass (Exposed) that defines > a static method which is a decorator (expose) such that any derived > class can mark a method with @Exposed.expose and it will then be later > returned by getExposedMethods(), a la: > > class Exposed: > @staticmethod > def expose( f ): > ... > > def getExposedMethods( self ): > ... > > class Person( Exposed ): > @Exposed.expose > def talk( self, ... ): > ... > > I'm trying to implement the decorator by having it populate a static > member list of whatever class it's in with a reference to the method. > getExposedMethods() would then return the contents of each of those > lists from itself back to Exposed in the class hierarchy. The first > problem was that having a reference to the method (i.e. talk()) does > not allow you to get a reference to the enclosing class (I had hoped > im_class would lead me there).
Not yet. When your decorator is called, the class object is not yet created, and what you are decorating is a plain function. > The real hiccup was that explicitly > passing the class as an argument to the decorator generates a undefined > global name error, presumably because at that point of execution the > class object hasn't been fully created/initialised. Exactly. > So how can this be done? The simplest thing is to use a two-stages scheme : mark the functions as exposed, then collect them: def expose(func): func._exposed = True return func def exposed(obj): return callable(obj) and getattr(obj, '_exposed', False) class Exposing(object): @classmethod def get_exposed_methods(cls): try: exposeds = cls._exposed_methods except AttributeError: exposeds = [] for name in dir(cls): obj = getattr(cls, name) if exposed(obj): exposeds.append(obj) cls._exposed_methods = exposeds return exposeds class Parrot(Exposing): @expose def parrot(self, what): return "%s says %s" % (self, str(what)) HTH -- bruno desthuilliers python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')])" -- http://mail.python.org/mailman/listinfo/python-list