?
Python是一門強類型的動態語言。
字面常量,變量沒有類型,變量只是在特定的時間指向特定的對象而已,變量所指向的對象是有類型的。
變量:變量在賦值時被創建,它可以是任何對象的引用,但必須在引用前被賦值。
?
舉例來說:當我們如下賦值時:
a = 3 # 給一個對象3賦予變量a
對于上面的賦值,Python將會明確的執行3個步驟來響應這個語句:
創建一個對象代表值3;
如果不存在變量a,就創建變量a;
把變量a與新創建的對象3關聯。
變量隨著賦值操作出現的。變量和對象是被存儲在不同的內存空間中的。變量與對象通過指針相關聯。變量永遠指向對象且永不指向變量。隨著賦值a = 3語句的執行,變量a就變成了對象3的一個引用。
如果你想學習Python可以來這個群,首先是472,中間是309,最后是261,里面可以學習和交流,也有資料可以下載。
變量與對象之間的鏈接在Python中稱之為引用。也就是說,一個引用也就是一種關聯,在內存中以指針的形式實現。
變量、對象與引用的區別:
+ 變量 是Python解釋器系統表中的一些條目, 它們是用來指向對象的。
+ 對象 是一些列的被分配的內存, 有足夠的空間存儲與之相關的數據類型。
+ 引用 自動地跟隨在變量與對象之間。
對象才有類型, 而變量沒有。一個例子:
a = 3 # a是一個整型數據
a = ‘spam’ # 現在是一個字符串了
a = 1.23 # 現在是一個浮點數了
在Python中,事情工作的很簡單,再次強調:Names沒有類型;只有對象有類型,而不是變量。
變量的命名規則:
只能包含字母、數字和下劃線
只能以字母或下劃線開頭
不能是Python解釋器的保留字
共享引用
接下來我們看兩個變量同時指向一個對象的情況:
a = 3
b = a
現在,假設我們再進行如下的賦值語句:
a = 3
b = a
a = ‘spam’
現在變量a指向的對象spam。然而變量b卻依然指向對象3。賦值意味著創建了新的對象。
共享引用與原地改變
接下來要看的是有一些對象會進行原地改變,那就是Python的可變對象,包括列表,字典及集合。對于一個支持原地改變的對象,我們需要知道共享引用,如果一個改變會影響其他的對象。還是看個例子吧:
L1 = [2, 3, 4]
L2 = L1
L1是一個列表且包含2、3、4三個對象。列表中的元素通過它們的位置進行訪問,所以L1[0]指向對象2,它是列表L1的第一個對象。當然列表也是一個對象,就像其他的整數與字符串。當進行上面的兩個賦值后,L1與L2都指向了同一個共享的對象。
現在,我們進行如下的賦值:
L1 = 24
這個賦值語句簡單地把L1指向了不同的對象;L2依然指向原來的列表。接下來我們進行一些改變:
L1 = [2, 3, 4] # 一個可變的對象
L2 = L1 # L2與L1指向了同樣的對象
L1[0] = 24 # 一個原地改變的操作
L1 # L1已經改變了
[24, 3, 4]
L2 # L2也是與L1相同
[24, 3, 4]
上面的例子中,我們并沒有改變L1對象本身,只是改變了L1中的一個對象。這種原地改變的操作的情況只出現在可變對象中。舉個字典的例子:
d1 = {‘a’: 1, ‘b’: 2}
d2 = d1
d1
{‘b’: 2, ‘a’: 1}
d2
{‘b’: 2, ‘a’: 1}
d1[‘a’] = ‘a’
d2
{‘b’: 2, ‘a’: ‘a’}
我們可以使用copy的方法:
L1 = [2, 3, 4]
L2 = L1[:] # 制作L1的拷貝
L1[0] = 24
L1
[24, 3, 4]
L2 # L2并沒有改變
[2, 3, 4]
通過上面的例子我們發現,L1的改變并沒有影響L2,L2只是引用了L1的一份拷貝,并不是原來的L1自身,也就說,L1與L2指向了兩個不同的內存空間。
接下來談論另外一個話題,Python會緩存小的整數及小的字符串。舉個例子吧:
L = [1, 2, 3]
M = L # M與L指向相同的對象
L == M # 具有相同的值
True
L is M # 依然相同
True
id(L)
4338913608
id(M)
4338913608
通過上面的例子,==判斷兩個引用的對象是否有相同的值;第二個操作符is是用來判斷對象id的,只有兩個names指向相同的對象,is比==判斷對象是否相同更強壯。is只是簡單地比較兩個對象的指針。再看一個例子:
L = [1, 2, 3]
M = [1, 2, 3] # M與L指向不同的對象(賦值意味著產生新的對象)
L == M # 具有相同的值
True
L is M # 但是是不同的對象
False
id(L)
4338913480
id(M)
4338915208
評論
查看更多