I have classes like this:
class Tool(object): def do_async(*args): pass for which I want to automatically generate non-async methods that make use of the async methods:
class Tool(object): def do_async(*args): pass def do(*args): result = self.do_async(*args) return magical_parser(result) This gets to be particularly tricky because each method needs to be accessible as both an object and class method, which is normally achieved with this magical decorator:
class class_or_instance(object): def __init__(self, fn): self.fn = fn def __get__(self, obj, cls): if obj is not None: f = lambda *args, **kwds: self.fn(obj, *args, **kwds) else: f = lambda *args, **kwds: self.fn(cls, *args, **kwds) functools.update_wrapper(f, self.fn) return f How can I make these methods, and make sure they're accessible as both class and object methods? This seems like something that could be done with decorators, but I am not sure how.
(Note that I don't know any of the method names in advance, but I know that all of the methods that need new buddies have _async at the end of their names.)
I think I've gotten fairly close, but this approach does not appropriately set the functions as class/object methods:
def process_asyncs(cls): methods = cls.__dict__.keys() for k in methods: methodname = k.replace("_async","") if 'async' in k and methodname not in methods: @class_or_instance def method(self, verbose=False, *args, **kwargs): response = self.__dict__[k](*args,**kwargs) result = self._parse_result(response, verbose=verbose) return result method.__docstr__ = ("Returns a table object.\n" + cls.__dict__[k].__docstr__) setattr(cls,methodname,MethodType(method, None, cls))
staticmethodif you're really, absolutely sure these things need to be methods.