Python中的可變與不可變物件

2021-09-13 17:04:37 字數 3180 閱讀 1619

python中的所有東西都是乙個物件。每個python新手都應該學習的是,python中的所有物件都可以是可變的或不可變的。

讓我們更深入地了解它的細節...因為python中的所有東西都是物件,所以每個變數都包含乙個物件例項。當乙個物件被初始化時,它被分配乙個唯一的物件id。它的型別是在執行時定義的,一旦設定永遠不會改變,但是如果它是可變型別它的狀態是可以被改變的。簡單地說,乙個可變物件可以在建立之後被改變,乙個不可變物件不能。

諸如(int,float,bool,str,tuple,unicode)等內建型別的物件是不可變的。像(list,set,dict)這樣的內建型別的物件是可變的。自定義類通常是可變的。要模擬類中的不變性,應該覆蓋屬性設定和刪除以引發異常。

現在出現這個問題,我們如何確定我們的變數是乙個可變物件還是不可變物件。為此,我們應該了解「id」和「type」函式的用途。

內建函式id()以整數形式返回物件的標識。這個整數通常對應於物件在記憶體中的位置,雖然這是針對python的實現和正在使用的平台而言。is運算子用來比較兩個物件的標識。

內建函式type()返回乙個物件的型別。讓我們看乙個簡單的例子

'''示例1''' 

>>> x =「holberton」

>>> y =「holberton」

>>> id(x)

140135852055856

>>> id(y)

140135852055856

>>> print(x is y)' ''比較型別'''

真的'''示例2'''

>>> a = 50

>>> type(a)

>>> b =「holberton」

>>> type(b)

現在我們已經看到了如何比較兩個簡單的字串變數來找出型別和id。因此,使用這兩個函式,我們可以檢查不同型別的物件是如何與變數相關聯以及如何更改物件的。

正如我們前面所討論的,乙個可變物件可以改變它的狀態或內容,不可變物件不能。

乙個實用的例子來找出物件型別的可變性

x = 10

x = y

我們正在建立乙個int型別的物件。識別符號x和y指向同乙個物件。

id(x)== id(y)

id(y)== id(10)

如果我們做乙個簡單的操作。

x = x + 1
現在

id(x)!= id(y)

id(x)!= id(10)

x被標記的物件被改變。物件10從未被修改過。不可變物件在建立後不允許修改

在可變物件的情況下

m = list([1,2,3])

n = m

我們正在建立乙個型別列表的物件。識別符號m和n被標記為同乙個列表物件,它是3個不可變的int物件的集合。

id(m)== id(n)
現在從列表物件中彈出乙個元素確實會改變物件,

m.pop()
物件id不會被更改

id(m)== id(n)
m和n將在修改後指向同乙個列表物件。列表物件現在將包含[1,2]。

那麼從上面的例子中我們看到了什麼?

python以不同方式處理可變物件和不可變物件。

不可變的訪問比可變物件更快。

當你需要改變物件的大小,例如列表,字典等等時,可變物件是很好用的。當你需要確保你建立的物件始終保持不變時,使用不可變物件。

不可變物件對於「更改」而言基本上是昂貴的,因為這樣做涉及到建立副本。更改可變物件很便宜。

並非所有的不可變物件都是不可變的。

如前所述,python容器比如元組,是不可變的。這意味著乙個tuple的值在建立後無法更改。但是元組的「值」實際上是一系列名稱,它們與物件的繫結是不可改變的。關鍵點是要注意繫結是不可改變的,而不是它們繫結的物件。

讓我們考慮乙個元組t =('holberton',[1,2,3])

上面的元組t包含不同資料型別的元素,第乙個元素是乙個不可變的字串,第二個元素是乙個可變列表。元組本身不可變。即它沒有任何改變其內容的方法。同樣,字串是不可變的,因為字串沒有任何可變方法。但是列表物件確實有可變方法,所以可以改變它。這是乙個微妙的點,但是非常重要:不可變物件的「值」 不能改變,但它的組成物件是能做到改變的。

對於我們來說,了解可變型別和不可變型別之間的區別以及將它們傳遞到函式時如何處理是非常重要的。當使用正確的物件時,儲存效率會受到很大影響。

例如,如果乙個可變物件在函式中被引用呼叫,它可以改變原來的變數本身。因此為了避免這種情況,需要將原始變數複製到另乙個變數中。不可變的物件可以通過引用來呼叫,因為它的值不能被改變。

def updatelist(list1):

list1 + = [10]

n = [5,6]

print(id(n))#140312184155336

updatelist(n)

print(n)#[

5,6,10 ] print(id(n))#140312184155336

從上面的例子我們可以看到,我們通過引用呼叫了列表,因此對原始列表本身進行了更改。

讓我們看看另乙個例子:

def updatenumber(n):

print(id(n))

n + = 10

b = 5

print(id(b))#10055680

updatenumber(b)#10055680

print(b)#5

在上面的例子中,同乙個物件被傳遞給函式,但即使物件是相同的,變數值也不會改變。這被稱為按價值傳遞 。那麼到底發生了什麼?當函式呼叫該值時,只傳遞該變數的值,而不傳遞該物件本身。所以引用該物件的變數不會改變,但物件本身正在改變,但僅在函式範圍內。因此,這種變化沒有體現出來。

Python中不可變與可變

在python的資料型別中,有用可變和不可變的兩種型別,那下面就來看一看兩種資料型別有什麼區別 old var hello print old var hello new var old var new var world print old var hello world 這符合我們的邏輯嗎?是不...

python可變與不可變

可變與不可變型別的實質實際上就是儲存機制的不同 不可變型別 比如字串 被稱為不可變的字串行,每個字元底層均有規範的unicode碼對應,記憶體規定無法對單一的乙個字元進行修改,要修改字串必須重新指向乙個全新的字串 可變型別 一方面,該列表可以保證在位址不變的前提下,改變列表內容 另一方面,該引用也可...

python可變與不可變

不可變作用和意義 物件所指的記憶體中的值是可以改變的。變數名儲存的是乙個位址,該位址指向乙個具體的物件,並且不管對變數的值進行怎樣的操作,都不會改變變數名的儲存位址。字典dict 列表list 集合set 1.list list1 1 2,3 4 print list1,id list1 1,2,3...