1. 程式人生 > >Python變數和物件

Python變數和物件

總結

在Python中一切都是物件,變數總是存放物件引用。當沒有變數指向物件時,這個物件便進入了垃圾收集過程。Python的“動態型別”機制,負責檢查變數的物件引用適用操作。如果該物件不適用該操作,則會直接報錯。一句話”變數無型別,物件有型別 “。

Python變數

Python中若要使用變數,不需要提前宣告,也不需要指定型別,只需要在用的時候,給變數賦值即可。

Python中一切都是物件,賦值的作用就是讓變數指標指向某個物件,也就是說變數中存放的物件的引用,而物件的引用是指向這個物件。以下面語句為例:

x = "blue"
y = "green"
z = x

python執行第一句時,在heap

中首先建立str物件,其文字內容為blue,同時還建立變數名為x的物件引用,x引用的就是這個str物件;

第二句類似,建立變數y指向str物件;第三句建立變數z的新物件引用,並將其指向物件引用x指向的相同物件。


可以看出在Python中賦值操作符號“=”的作用是,將物件引用和記憶體中的某個物件進行繫結。如果物件已經存在,就進行簡單的重新繫結,以便引用“=”右邊的物件;如果物件引用尚未存在,就首先建立物件,然後將物件引用和物件進行繫結。這很類似與c中的指標的概念。

動態型別機制

Python使用“動態型別”機制,也就是說,在Python程式中,任何時候可以根據需要,某個物件引用都可以重新繫結到另一個不同的物件上(不要求是相同的型別)

,這和其他強化型語言如(C++,Java)不太一樣,只允許重新繫結相同型別的物件上。在Python中,因為有“動態型別”機制,所以一個物件引用可以執行不同型別的物件適用的方法。當一個物件不存在任何物件引用的時候,就進入了垃圾收集的過程。(Python自動回收機制)

如下語句示例:

a = 100
print a / 10
10
print a[0]
Traceback (most recent call last):
  File "<string>", line 1, in <fragment>
TypeError: 'int' object has no attribute '__getitem__'
a = "hello"
print a[0]
h
a / 10
Traceback (most recent call last):
  File "<string>", line 1, in <fragment>
TypeError: unsupported operand type(s) for /: 'str' and 'int'

Python執行第一句時在heap中建立int物件,其內容為100,同時建立物件引用a,其值指向heap中int物件;

第二句“a/10”,Python適用“動態型別機制”,判斷a指向物件是int型,可以使用除法操作,便進行運算產生結果;

第三句,由於a指向int型,並不適用[](分片)操作,於是報錯;

第四句,Python會在heap中建立str物件,其內容為hello,同時改變a變數,使其值指向heap中str物件,同時原來int物件,由於不存在物件引用,就進入垃圾回收過程;

後續語句類似操作。


id(),==,is差別

1、id():獲取物件在記憶體中的地址

2、is:比對2個變數的物件引用(物件在記憶體中的地址,即id() 獲得的值)是否相同。如果相同則返回True,否則返回False。換句話說,就是比對2個變數的物件引用是否指向同一個物件。

3、==:對比2個變數指向物件的內容是否相同。

l1 = [1, 2, 3]
l2 = [1, 2, 3]
print l1 == l2 <span style="font-family: Arial, Helvetica, sans-serif;">#兩個變數指向物件值相等,故返回true</span>
print l1 is l2 <span style="font-family: Arial, Helvetica, sans-serif;">#l1和l2貌似指向同一個物件[1, 2, 3],但在記憶體中其實是兩塊不相關的東西,故返回false</span>

l3 = l1
print l3 is l1 #l3和l1指向同一個物件,故返回true
l3[0] = 4
print l1 #[4, 2, 3]
print l3 #[4, 2, 3]
print l2 #[1, 2, 3]

a = 100
b = 100
print a is b #不同於list物件,返回true

可變物件list和不可變物件