2 回答
TA贡献1828条经验 获得超3个赞
如果有人return_item从 Python 调用函数,他们可能会这样做:
something = Something()
something_else = return_item(something)
del something
如果return_item没有返回传入的参数,而是返回其他内容,您会期望此时something传入的参数应该从内存中释放,因为它的引用计数下降到零。
如果你不Py_INCREF返回相同的对象,那仍然会发生 - 对象的引用计数将下降到 0,并且你将在something_else.
TL;DR:是的,你应该这样做Py_INCREF,因为你通过从函数返回该对象创建了另一个引用。
TA贡献1998条经验 获得超6个赞
您不想在返回之前增加对象的引用计数。这样做会造成内存泄漏,从而阻止对象被垃圾回收。
将引用计数增加为“我正在使用此内存。请不要释放它”。当你输入 C 代码时,你从 Python 中“借用”了引用,但是当你退出 C 代码时,你已经完成了对象并且不再需要引用了。
Python 中的变量和底层内存是分开的,这使得它在内存方面有些效率(阅读更多)。另一个答案忽略了分配给something_else增加底层内存的引用计数的事实。您可以使用 自己验证这一点sys.getrefcount。
import sys
something = "hello"
print(sys.getrefcount(something)) # 2 (getrefcount uses a reference)
something_else = something
print(sys.getrefcount(something_else)) # 3 (same memory as something)
del something
print(sys.getrefcount(something_else)) # 2
print(something_else) # "hello"
两者都something引用something_else了相同的内存(包含文本“hello”的字符串)。删除一个不会影响另一个。尽管您的代码使用了 C 函数,但基本原理是相同的。尝试用你的 C 函数的两个版本打印出引用计数,它会更清楚。
您不想做的是Py_DECREF在返回对象之前调用。在这种情况下,引用计数可能会降至零,并且返回的东西完全无效。
添加回答
举报