2 回答

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超3個(gè)贊
如果有人return_item從 Python 調(diào)用函數(shù),他們可能會(huì)這樣做:
something = Something()
something_else = return_item(something)
del something
如果return_item沒(méi)有返回傳入的參數(shù),而是返回其他內(nèi)容,您會(huì)期望此時(shí)something傳入的參數(shù)應(yīng)該從內(nèi)存中釋放,因?yàn)樗囊糜?jì)數(shù)下降到零。
如果你不Py_INCREF返回相同的對(duì)象,那仍然會(huì)發(fā)生 - 對(duì)象的引用計(jì)數(shù)將下降到 0,并且你將在something_else.
TL;DR:是的,你應(yīng)該這樣做Py_INCREF,因?yàn)槟阃ㄟ^(guò)從函數(shù)返回該對(duì)象創(chuàng)建了另一個(gè)引用。

TA貢獻(xiàn)1998條經(jīng)驗(yàn) 獲得超6個(gè)贊
您不想在返回之前增加對(duì)象的引用計(jì)數(shù)。這樣做會(huì)造成內(nèi)存泄漏,從而阻止對(duì)象被垃圾回收。
將引用計(jì)數(shù)增加為“我正在使用此內(nèi)存。請(qǐng)不要釋放它”。當(dāng)你輸入 C 代碼時(shí),你從 Python 中“借用”了引用,但是當(dāng)你退出 C 代碼時(shí),你已經(jīng)完成了對(duì)象并且不再需要引用了。
Python 中的變量和底層內(nèi)存是分開(kāi)的,這使得它在內(nèi)存方面有些效率(閱讀更多)。另一個(gè)答案忽略了分配給something_else增加底層內(nèi)存的引用計(jì)數(shù)的事實(shí)。您可以使用 自己驗(yàn)證這一點(diǎn)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了相同的內(nèi)存(包含文本“hello”的字符串)。刪除一個(gè)不會(huì)影響另一個(gè)。盡管您的代碼使用了 C 函數(shù),但基本原理是相同的。嘗試用你的 C 函數(shù)的兩個(gè)版本打印出引用計(jì)數(shù),它會(huì)更清楚。
您不想做的是Py_DECREF在返回對(duì)象之前調(diào)用。在這種情況下,引用計(jì)數(shù)可能會(huì)降至零,并且返回的東西完全無(wú)效。
添加回答
舉報(bào)