为什么将getrefcount放在函数内时增加2?

huangapple go评论78阅读模式
英文:

Why does getrefcount increase by 2 when put inside a function?

问题

考虑以下代码。

import sys

a = [1, 2, 3]

def foo(x):
    print(sys.getrefcount(x))

foo(a) # 输出4 -- 但为什么?

当我们调用 foo(a) 以及执行 print(sys.getrefcount(x)) 时,数组 [1, 2, 3] 被变量 a、函数 foo 的参数 x 以及 sys.getrefcount 的参数所引用。我预期应该打印出3。我错过了什么?

英文:

Consider the following code.

import sys

a = [1, 2, 3]

def foo(x):
    print(sys.getrefcount(x))

foo(a) # prints out 4 -- but why?

When we invoke foo(a) and when print(sys.getrefcount(x)) executes, the array [1, 2, 3] is referenced by a, by the parameter x of the function foo and by the parameter of sys.getrefcount. I expected 3 to be printed out. What have I missed?

答案1

得分: 2

<sub>声明:我远非CPython内部的专家。这个答案是我对CPython源代码的理解,可能不是完整的故事,也不适用于所有情况。</sub>


你所缺少的引用是局部变量x,它与参数引用不同。

在内部,调用foo是通过使用函数参数的元组调用PyObject_Call 来执行的。在这个元组中持有的强引用是在调用sys.getrefcount(x)时添加的唯一引用。然而,调用foo是不同的,因为在C代码中不会直接对参数进行操作,而是需要将它们作为本地变量提供,以便在后续的字节码执行期间可以访问。存储Python可访问的本地变量的结构保持对参数对象的自己的强引用。这就是为什么在调用Python函数时引用计数会第二次增加的原因。

英文:

<sub> Disclaimer: I am far from an expert in CPython internals. This answer is the best of my understanding of what's going on from having skimmed the CPython source code. It may not be the whole story, or applicable to all cases.</sub>


The reference you're missing is the local variable x, which is different from the argument reference.

Internally, the call to foo is carried out by invoking PyObject_Call with a tuple of the function arguments. The strong reference held by that tuple is the one reference that gets added in the case of calling sys.getrefcount(x). However, calling foo is different because the arguments aren't acted on directly in the C code but instead need to be made available as local variables that are accessible during the subsequent bytecode execution. The structure that stores the Python-accessible local variables keeps its own strong reference to the argument objects. Hence why the reference count gets incremented a second time when calling a Python function.

huangapple
  • 本文由 发表于 2023年3月4日 01:03:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/75629948.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定