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在返回對象之前調用。在這種情況下,引用計數可能會降至零,并且返回的東西完全無效。
添加回答
舉報