如何在Python函数中接受无限闭包?

时间:2018-06-20 22:07:17

标签: python recursion closures

我有如下代码:

    # Define a function
    def foo(x):
        # inner function "bar"
        def bar(y):
            q = 10
            # inner function "baz"
            def baz(z):
                print("Locals: ", locals())
                print("Vars: ", vars())
                return x + y + q + z
            return baz
        return bar

    # Locals: {'y': 20, 'x': 10, 'z': 30, 'q': 10}
    # Vars: {'y': 20, 'x': 10, 'z': 30, 'q': 10}

print(foo(10)(20)(30)) # 70

我该如何修改上述功能以接受无限制的呼叫并接受字符串...?

我们是否必须使用类似于编写装饰器的方式,或者是否有其他方法可以实现此目的?

print(foo(90)) 
print(foo()(90)) 
print(foo()()(90)) 
print(foo()()()('ss'))

1 个答案:

答案 0 :(得分:2)

这里的闭包捕获只是一种干扰,以不同的方式处理90ss 1 ,所以让我们把所有这些扔掉,然后解决您正在苦苦挣扎的问题。

首先,您需要一个函数,如果使用参数调用该函数,则执行一件事,如果不使用参数调用,则执行另一件事。这很容易;只需使用具有默认值的参数,或使用*args

第二,您要做的“不同的事情”是返回一个递归地执行与您的函数相同的功能的函数,除了在结果中附加一个额外的'o'。在定义递归数据结构时,无论是递归关闭还是递归defaultdict,最简单的方法通常是使用递归。

例如:

def foo(x=None, *, _chain=0):
    if x is None:
        def bar(*args):
            return foo(*args, _chain=_chain+1)
        return bar
    else:
        return 'f' + 'o'*_chain + x

可以bar重写为装饰器,并重写return bar(foo),但这似乎是不必要的。不会改变以下事实:这里的键是foo返回一个调用foo的函数。


1。如果您不知道该怎么做,只需if isinstance(x, str):。或者,如果您想花哨的话,请查找functools.singledispatch