Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python decorator for simple recursion? In standard library or elsewhere?

I'm looking for a Python decorator that can make a function recursive. I find myself writing a lot of functions like this:

def xyz(data):
    if not isinstance(data, TypeThatDenotesSingularity):
        return map(xyz, data)
    return singular_xyz(data)

I figure there must be a decorator out there somewhere (in the standard library?) that can slim down the notation a tad:

@recursive(TypeThatDenotesSingularity)
def xyz(data):
    return singular_xyz(data)

I have been searching but I can't seem to get anywhere. Perhaps I'm missing some essential terminology?

Thanks for pointing me in the right direction!

like image 784
Tim Molendijk Avatar asked Feb 16 '11 17:02

Tim Molendijk


1 Answers

How about this:

def recursive(stop_type):
    def _inner(func):
        def _recursive(data, *args, **kw):
            if not isinstance(data, stop_type):
                return map(_recursive, data)
            return func(data, *args, **kw)
        return _recursive
    return _inner

Explanation of how this works if used as @recursive(MySingularType)

  1. recursive is called at function decoration time with the argument stop_type set to MySingularType
  2. recursive returns closure _inner
  3. _inner is immediately called with the function to decorate, also at compile time
  4. _inner returns closure _recursive which is now the new function which is called when you call your decorated function

Now, when you call your function: _recursive is called. If the type matches, return the function result. Otherwise, map another call to _recursive, ad infinitum (well really ad until stackoverflowium)

Note You can omit the *args and **kwargs if the decorated function will always always only take a single value

like image 114
Crast Avatar answered Oct 10 '22 03:10

Crast