Python:使用关键字参数的递归函数的奇怪行为

时间:2010-09-02 23:32:27

标签: python recursion arguments keyword

我写了一个小片段来计算给定节点的路径长度(例如它到根节点的距离):

def node_depth(node, depth=0, colored_nodes=set()):
    """
    Return the length of the path in the parse tree from C{node}'s position
    up to the root node. Effectively tests if C{node} is inside a circle
    and, if so, returns -1.

    """
    if node.mother is None:
        return depth
    mother = node.mother
    if mother.id in colored_nodes:
        return -1
    colored_nodes.add(node.id)
    return node_depth(mother, depth + 1, colored_nodes)

现在这个函数发生了一件奇怪的事情(至少对我来说很奇怪):第一次调用node_depth会返回正确的值。但是,使用相同节点第二次调用它会返回-1。在第一次调用中,colored_nodes集为空,但包含第一次调用期间添加的所有节点ID:

print node_depth(node) # -->  9
# initially colored nodes --> set([])
print node_depth(node) # --> -1
# initially colored nodes --> set([1, 2, 3, 38, 39, 21, 22, 23, 24])

print node_depth(node, colored_nodes=set()) # --> 9
print node_depth(node, colored_nodes=set()) # --> 9

我在这里错过了一些特定于Python的东西,这应该是这样的吗?

提前致谢,

Jena的

2 个答案:

答案 0 :(得分:15)

Python中函数参数的“默认值”在函数声明时实例化,而不是每次调用函数时都实例化。您很少想要改变参数的默认值,因此使用不可变的默认值通常是个好主意。

在您的情况下,您可能希望执行以下操作:

def node_depth(node, depth=0, colored_nodes=None):
    ...
    if colored_nodes is None: colored_nodes = set()

答案 1 :(得分:6)

这是因为在Python中,每次调用函数时,默认参数值都是 not ,而在函数定义时只有一次。实际上,除了定义后的第一个调用之外,您在调用函数时使用预先填充的colored_nodes集合。