拥有规则
当一个对象引用传递进出一个函数时,函数的接口应该指定拥有关系的传递是否包含引用。
大多数函数返回一个对象的引用,并传递引用拥有关系。通常,所有创建对象的函数,例如 PyLong_FromLong() 和 Py_BuildValue() ,会传递拥有关系给接收者。即便是对象不是真正新的,你仍然可以获得对象的新引用。一个实例是 PyLong_FromLong() 维护了一个流行值的缓存,并可以返回已缓存项目的新引用。
很多另一个对象提取对象的函数,也会传递引用关系,例如 PyObject_GetAttrString() 。这里的情况不够清晰,一些不太常用的例程是例外的 PyTuple_GetItem() , PyList_GetItem() , PyDict_GetItem() , PyDict_GetItemString() 都是返回从元组、列表、字典里借用的引用。
函数 PyImport_AddModule() 也会返回借用的引用,哪怕可能会返回创建的对象:这个可能因为一个拥有的引用对象是存储在 sys.modules 里。
当你传递一个对象引用到另一个函数时,通常函数是借用出去的。如果需要存储,就使用 Py_INCREF() 来变成独立的拥有者。这个规则有两个重要的例外: PyTuple_SetItem() 和 PyList_SetItem() 。这些函数接受传递来的引用关系,哪怕会失败!(注意 PyDict_SetItem() 及其同类不会接受引用关系,他们是"正常的")。
当一个C函数被Python调用时,会从调用方传来的参数借用引用。调用者拥有对象的引用,所以借用的引用生命周期可以保证到函数返回。只要当借用的引用需要存储或传递时,就必须转换为拥有的引用,通过调用 Py_INCREF() 。
Python调用从C函数返回的对象引用时必须是拥有的引用---拥有关系被从函数传递给调用者。 |