开发者

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

开发者 https://www.devze.com 2023-02-11 02:19 出处:网络
I\'m looking for a Python decorator that can make a function recursive. I find myself writing a lot of functions like this:

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开发者_如何学Python 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!


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


I dunno about a decorator, but you could do it with a class if you find yourself rewriting the same pattern over and over.

class Recursive(object):
    def __init__(self, check_type, singular):
        self.check_type = check_type
        self.singular = singular

    def __call__(self, data):
        if not isinstance(data, self.check_type):
            return map(self, data)
        return self.singular(data)
0

精彩评论

暂无评论...
验证码 换一张
取 消