誰持有對象引用的全部權,誰就要對對象負責。code
引用的全部權對函數的返回值和參數有重大的意義。對象
傳遞引用的全部權指的是函數把引用的全部權和返回值一塊兒交個調用方。blog
把指向對象的引用返回給調用方的函數通常都會將全部權一塊兒交給調用方。若是函數的調用方拿到了引用的全部權,那麼在指向對象的引用結束時就要負起責任執 行減量操做。索引
生成新對象的全部函數負責把引用的全部權交給調用方。it
出借引用的全部權指的是函數只把返回值交給調用方,至於引用的全部權則只是出借。class
當調用方借到引用的全部權時,就不能對這個引用調用進行減量操做了。由於借走的全部權,不能隨意破壞。引用
借方只能在貸方的指按期限內持有對象,由於一旦過了這個期限,對象就有可能被釋放。因此借方必定要遵循貸方的規矩。im
在這種狀況下,調用方只是借到了引用的全部權,因此引用對象的計數器不增長。
可是爲何要借給調用方而不是直接給它引用權呢?這是由於咱們以爲若是調用方不想要整個對象,而是說只要對象的一部分。例如咱們只取鏈表中的一少部分,這樣的話也不用擔憂忘記減量操做而出現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個計數。
其實理解起來有一些困難。當往元組裏追加元素時候,實際上持有元素的不是調用方,而是元組。這樣顯得更加天然,用的得當能寫出靈活的代碼。
調用方把參數的引用權借給函數。
當函數的調用方要出借引用的全部權時,從把對象交給函數以後直到函數執行結束爲止, 這段時間調用方都必須保留指向對象的引用的全部權。
對於這個對象,只要調用方有一個全部權,那麼就直接把對象交給函數也無妨。但若是 調用方一個全部權也沒有,那麼對象就可能會被釋放,所以這裏必須執行增量操做來保留引 用的全部權