Python:带有关键字参数的递归函数的奇怪行为

发布于 2024-09-16 18:42:23 字数 1039 浏览 16 评论 0原文

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

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)

现在该函数发生了一件奇怪的事情(至少对我来说很奇怪): 为第一次返回正确的值。但是,使用同一节点第二次调用它会返回 -1。 color_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 的内容,而这确实应该是这样?

预先感谢,

耶拿

I've written a small snippet that computes the path length of a given node (e.g. its distance to the root node):

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)

Now there is a strange thing happening with that function (at least it is strange to me): Calling node_depth for the first time returns the right value. However, calling it a second time with the same node returns -1. The colored_nodes set is empty in the first call, but contains all node-IDs in the second call that have been added during first one:

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

Am I missing some Python-specific thing here and this is really supposed to be that way?

Thanks in advance,

Jena

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱你不解释 2024-09-23 18:42:23

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

在你的情况下,你可能想做这样的事情:

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

The "default value" for a function parameter in Python is instantiated at function declaration time, not every time the function is called. You rarely want to mutate the default value of a parameter, and so it's often a good idea to use something immutable for the default value.

In your case you may want to do something like this:

def node_depth(node, depth=0, colored_nodes=None):
    ...
    if colored_nodes is None: colored_nodes = set()
软糖 2024-09-23 18:42:23

这是因为在 Python 中,每次调用函数时都不会计算默认参数值,而只会在函数定义时计算一次。因此,实际上,除了定义后的第一次调用之外,您在每次调用时都使用预先填充的 colored_nodes 设置来调用该函数。

This is, because in Python, the default argument values are not evaluated each time the function is called, but only once at function definition time. So effectively, you are calling the function with a pre-filled colored_nodes set on every but the first call after definition.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文