哈嘍大家好,我是咸魚。
前天有個(gè)小伙伴找到我,給了我一段 python 代碼:
a = [1, 2]a[1] = aprint(a[1])然后問我為什么結(jié)果是 [1, [...]],我一看這個(gè)問題有意思,我說三言兩語解釋不清楚,寫篇文章到時(shí)候你看下吧,于是有了今天這篇文章。
在正式開始之前,讓我們先弄清楚一些概念。

"Python 中一切皆對(duì)象",相信這句話大家在學(xué)習(xí) Python 的時(shí)候都已經(jīng)聽的耳朵起繭子了吧。
在 Python 中,所有的數(shù)據(jù)都是對(duì)象,包括基本數(shù)據(jù)類型(例如整數(shù)、浮點(diǎn)數(shù)、字符串等)以及用戶自定義的類型(類的實(shí)例等)。
而對(duì)象其實(shí)是內(nèi)存中分配的一塊空間,用來存儲(chǔ)其值。每個(gè)對(duì)象都有一個(gè)唯一的標(biāo)識(shí)符(id),可以通過 id() 函數(shù)獲取。
不但如此,每一個(gè)對(duì)象都具有兩個(gè)標(biāo)準(zhǔn)的頭部信息:

在 Python 中,變量實(shí)際上是對(duì)象的【引用】,而不是對(duì)象本身的【存儲(chǔ)】。當(dāng)我們執(zhí)行賦值語句時(shí),會(huì)自動(dòng)建立變量和對(duì)象之間的關(guān)系,即引用。
變量就像是一個(gè)指針,【指向】?jī)?nèi)存中存儲(chǔ)對(duì)象的位置。
我們來看一個(gè)例子:
a = 1b = aa = a + 1首先將 1 賦值于 a,即 a 指向了 1 這個(gè)對(duì)象。

接著 b = a 則表示讓變量 b 也同時(shí)指向 1 這個(gè)對(duì)象。Python 的對(duì)象可以被多個(gè)變量所指向(引用)。

最后執(zhí)行 a = a + 1,在這里需要注意的是,Python 的基礎(chǔ)數(shù)據(jù)類型(例如整型(int)、字符串(string)等)是不可變的
所以,a = a + 1,并不是讓 a 的值增加 1,而是表示重新創(chuàng)建了一個(gè)新的值為 2 的對(duì)象,并讓 a 指向它。但是 b 仍然不變,仍然指向 1 這個(gè)對(duì)象。
因此最后的結(jié)果是,a 的值變成了 2,而 b的值不變?nèi)匀皇?nbsp;1。

通過這個(gè)例子你可以看到,這里的 a 和 b,開始只是兩個(gè)指向同一個(gè)對(duì)象的變量而已,或者你也可以把它們想象成同一個(gè)對(duì)象的兩個(gè)名字。
簡(jiǎn)單的賦值 b = a,并不表示重新創(chuàng)建了新對(duì)象,只是讓同一個(gè)對(duì)象被多個(gè)變量指向或引用。
在了解了變量、對(duì)象、引用、賦值之后,我們回到一開始的例子。
a = [1, 2]a[1] = aprint(a[1])這段代碼中創(chuàng)建了一個(gè)列表 a,其中包含兩個(gè)元素(1 和 2),然后 a[1] 被賦值為整個(gè)列表 a(a[1] = a),當(dāng)你打印 a[1] 時(shí),它實(shí)際上是指向列表 a 本身。
a = [1, <reference to a>]這樣就會(huì)導(dǎo)致循環(huán)引用的問題。

我們來分步驟解釋一下這個(gè)過程:
那如何避免循環(huán)引用呢?可以使用淺拷貝或者深拷貝來解決。
我們用淺拷貝來試一下:
import copya = [1, 2]a[1] = copy.copy(a)print(a[1])# 結(jié)果是[1,2]淺拷貝創(chuàng)建一個(gè)新的對(duì)象,然后將原始對(duì)象中的元素復(fù)制到新對(duì)象中。但是,如果原始對(duì)象的元素是可變對(duì)象(例如列表),那么淺拷貝只會(huì)復(fù)制對(duì)象的引用而不是對(duì)象本身。
就比如上面的例子:
本文鏈接:http://m.www897cc.com/showinfo-26-68339-0.htmlPython 變量?對(duì)象?引用?賦值?一個(gè)例子解釋清楚
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com