代码之家  ›  专栏  ›  技术社区  ›  Rafe Kettler

有没有办法判断我是否在Python中使用递归?

  •  1
  • Rafe Kettler  · 技术社区  · 14 年前

    我正在编写一个函数来遍历用户的文件系统,并创建一个表示该目录的树(该树实际上是Tkinter中的TreeView小部件,但在功能上它是一棵树)。

    我能想到的最好的方法就是递归。但是,我在函数中的一个例子要求我知道它是否是“原始”函数调用,在这种情况下,文件没有父节点,或者它是否是“递归”函数调用,即函数本身进行的调用,以便我可以给这些文件一个适当的父节点。

    5 回复  |  直到 14 年前
        1
  •  4
  •   viraptor    14 年前

    这似乎是一个奇怪的情况,对于特定的功能来说,工作太多了。你必须建造这棵树-为什么你需要知道它附着在哪里?为什么不直接构建你负责的节点并返回它们呢?

    def make_tree(path):
        return [
            make_tree(os.path.join(path, element))
            for element in get_elements(path)]
    

    如果您真的想集成它,只需传递父级:

    def make_tree(path, parent_node = None):
        new_node = Node(...)
        for ....:
            make_tree(path+..., new_node)
    
        if parent_node is not None:
            parent_node.add(new_node)
        else:
            .....
    
        2
  •  7
  •   Jim Brissom    14 年前

        3
  •  1
  •   miku    14 年前

    在调用递归的同时包含对父级的引用或某个级别的信息,这应该是简单而常见的。

    另一种方法(虽然我不喜欢)是使用蟒蛇 inspect 模块,它允许您检查例如调用堆栈。举个例子:

    #!/usr/bin/env python
    
    import inspect
    
    def whocalled():
        return inspect.stack()[2][3]
    
    def fib(n):
        print n, whocalled()
        if n < 2:
            return n
        return fib(n - 1) + fib(n - 2)
    
    if __name__ == '__main__':
        fib(4)
    

    将打印:

    4 <module>
    3 fib
    2 fib
    1 fib
    0 fib
    1 fib
    2 fib
    1 fib
    0 fib
    
        4
  •  1
  •   Sean    14 年前

    inspect 模块。

    import inspect
    
    def whoami():
        '''Returns the function name of the caller.'''
    
        return inspect.stack()[1][3] #Stack data for the name of the function
    
    def caller():
        '''Returns the caller of a function.'''
    
        return inspect.stack()[2][3] #Stack data for the name of whatever calls this
    
    caller = caller()
    

    如果尝试从中调用索引,则会出现索引超出范围错误 __main__

    when the caller of the function != whoami() -> no longer recursing.
    
        5
  •  1
  •   Jochen Ritzel    14 年前

    我真想知道你为什么把事情弄得这么复杂。您可以简单地将函数分为递归部分和非递归部分!下面是一个简单的例子:

    def countdown(n):
        " original function "
        print "Ok, start the countdown (not recursive)"
    
        msg = "We are at"
    
        def recursive( x ):
            " recursive part "
            if x >= 0:
                print msg, x, "(recursive)"
                return recursive(x-1)
    
        return recursive(n)
    
    countdown(10)
    

    在现实中,你甚至不需要太多的论据来解释问题 recursive