Python对象引用的所有权

引用所有权

谁持有对象引用的所有权,谁就要对对象负责。

引用的所有权对函数的返回值和参数有重大的意义。

传递引用的所有权--返回值

传递引用的所有权指的是函数把引用的所有权和返回值一起交个调用方。

把指向对象的引用返回给调用方的函数一般都会将所有权一起交给调用方。如果函数的调用方拿到了引用的所有权,那么在指向对象的引用结束时就要负起责任执 行减量操作。

生成新对象的所有函数负责把引用的所有权交给调用方。

出借引用的所有权--返回值

出借引用的所有权指的是函数只把返回值交给调用方,至于引用的所有权则只是出借。

当调用方借到引用的所有权时,就不能对这个引用调用进行减量操作了。因为借走的所有权,不能随意破坏。

借方只能在贷方的指定期限内持有对象,因为一旦过了这个期限,对象就有可能被释放。所以借方一定要遵循贷方的规矩。

在这种情况下,调用方只是借到了引用的所有权,所以引用对象的计数器不增加。
但是为什么要借给调用方而不是直接给它引用权呢?这是因为我们觉得如果调用方不想要整个对象,而是说只要对象的一部分。例如我们只取链表中的一少部分,这样的话也不用担心忘记减量操作而出现BUG。

占据引用的所有权--参数

当调用方把参数传递给函数时,函数优势会占据这个参数的引用所有权。当对象的引用权被占用时,调用方就没有责任对这个对象进行减量操作了。

int PyTuple_SetItem(register PyObject *op,register Py_ssize_t i,PyObject *newitem)
{    
    register PyObject *olditem;
    register PyObject **p;
    p = ((PyTupleObject *)op) -> ob_item + i;
    olditem = *p;/* 取出原本存有的对象 */
    *p = newitem;/* 追加到元组 */
    Py_XDECREF(olditem);/* 对取出的对象进行减量操作 */
    return 0;
    }

上面的函数负责将元素追加到元组。其参数分别是,元组,索引,要追加的元素。

但是这里并没有给要追加的元素计数器加一,按道理来说必须加一才对。这就是占有引用的所有权。

在这个例子中,虽然是从元组引用的,但是故意不给这个引用进行增量操作,以此夺取调用方的1个计数。

其实理解起来有一些困难。当往元组里追加元素时候,实际上持有元素的不是调用方,而是元组。这样显得更加自然,用的得当能写出灵活的代码。

出借引用的所有权--参数

调用方把参数的引用权借给函数。

当函数的调用方要出借引用的所有权时,从把对象交给函数之后直到函数执行结束为止, 这段时间调用方都必须保留指向对象的引用的所有权。

对于这个对象,只要调用方有一个所有权,那么就直接把对象交给函数也无妨。但如果 调用方一个所有权也没有,那么对象就可能会被释放,因此这里必须执行增量操作来保留引 用的所有权

posted on 2018-12-18 15:27  Léon_The_Pro  阅读(358)  评论(0编辑  收藏  举报

导航