中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

深入淺析Python傳值與傳址

發布時間:2020-09-08 17:29:05 來源:腳本之家 閱讀:150 作者:Salane 欄目:開發技術

1. 傳值與傳址的區別

傳值就是傳入一個參數的值,傳址就是傳入一個參數的地址,也就是內存的地址(相當于指針)。他們的區別是如果函數里面對傳入的參數重新賦值,函數外的全局變量是否相應改變:用傳值傳入的參數是不會改變的,用傳址傳入就會。

def a(n):
  n[2] = 100
  print(n)
  return None
def b(n):
  n += 100
  print(n)
  return None
an = [1,2,3,4,5]
bn = 10
print(an)
a(an)
print(an)
print(bn)
b(bn)
print(bn)
[1, 2, 3, 4, 5]
[1, 2, 100, 4, 5]
[1, 2, 100, 4, 5]
10
110
10

在上面的例子中,an是一個list,將其作為實參傳入函數a中,a對其第三個元素進行修改。a執行結束后再次打印an,發現里面的元素的確發生變化,這就是傳址操作。bn代表一個數字,將其傳入函數b,并做修改,b執行結束后再次打印bn,沒有變化,這是傳值操作。

2. Python中傳值與傳址的規律

Python是不允許程序員選擇采用傳值還是傳址的。Python參數傳遞采用的是“傳對象引用”的方式,實際上,這種方式相當于傳值和傳址的一種綜合。

如果函數收到的是一個可變對象(比如字典或者列表)的引用,就能修改對象的原始值——相當于傳址。如果函數收到的是一個不可變對象(比如數字、字符或者元組)的引用,就不能直接修改原始對象——相當于傳值。所以python的傳值和傳址是根據傳入參數的類型來選擇的。

傳值的參數類型:數字,字符串,元組

傳址的參數類型:列表,字典

3. 內置函數id

內置函數id,負責顯示一個變量或者數據在內存中的地址,有時可以用來檢測所使用的對象是否為同一個,幫助區別傳值與傳址操作。

但是id在有些情況下比較特殊,注意下面的例子。

a = 100
b = 200 
print(id(a))
print(id(b))
c = a
print(id(c))
print(a is c)
a += 300
print(a)
print(c)
print(a is c)
print(id(a))
print(id(c))
1549495552
1549498752
1549495552
True
400
100
False
93638128
1549495552

為了提高內存利用效率,對于一些簡單的對象,如一些數值較小的int對象,python采取重用對象內存的辦法。如指向a=100,c=100時,由于100作為簡單的int類型且數值小,python不會兩次為其分配內存,而是只分配一次,然后將a與c同時指向已分配的對象。但是當a的值發生變化時,會單獨為a重新分配一個新的內存。

4. list傳值與傳址

list類型使用簡單的賦值操作,是傳址。

a = [1,2,3,4,5]
b = a
print(a)
b[2] = 333
print(a)
print(b)
print(id(a))
print(id(b))
[1, 2, 3, 4, 5]
[1, 2, 333, 4, 5]
[1, 2, 333, 4, 5]
96142472
96142472

copy函數是淺拷貝,是傳值。python2中,需要import copy模塊,python3可直接使用。

a = [1,2,3,4,5]
b = a.copy()
print(a)
b[2] = 333
print(a)
print(b)
print(id(a))
print(id(b))
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[1, 2, 333, 4, 5]
92990536
96202632

由于copy是淺拷貝,只拷貝一層的內容,當遇到下列情況時,copy不能實現完全的傳值操作。

a = [1,2,3,[10,20,30]]
b = a.copy()
print(id(a))
print(id(b))
print(id(a[3]))
print(id(b[3]))
a[3][2] = 666
print(a)
print(b)
96141704
93355400
96141768
96141768
[1, 2, 3, [10, 20, 666]]
[1, 2, 3, [10, 20, 666]]

要解決這個問題,需要使用deepcopy。python3中,直接可以使用copy()方法,但deepcopy()還是需要導入copy模塊。

import copy
a = [1,2,3,[10,20,30]]
b = copy.deepcopy(a)
print(id(a))
print(id(b))
print(id(a[3]))
print(id(b[3]))
a[3][2] = 666
print(a)
print(b)
96503944
93002376
96886024
93352712
[1, 2, 3, [10, 20, 666]]
[1, 2, 3, [10, 20, 30]]

5. tuple操作

tuple元組是不可修改的,指的是其元組內容不可改。

t1 = (1,2,3)
t1[1] = 100
---------------------------------------------------------------------------
TypeError                 Traceback (most recent call last)
<ipython-input-19-9caf76a526a9> in <module>()
   1 t1 = (1,2,3)
----> 2 t1[1] = 100
TypeError: 'tuple' object does not support item assignment

但是其所指向的內存地址是可變的。

t1 = (1,2,3)
t2 = (5,6,7)
print(id(t1))
t1 += t2
print(t1)
print(id(t1))
print(id(t2))
t2 *= 3
print(t2)
print(id(t2))
96151520
(1, 2, 3, 5, 6, 7)
93048552
94080672
(5, 6, 7, 5, 6, 7, 5, 6, 7)
93656912

并不是起初的t1和t2所指向的元組內容發生了變化,而是新分配了兩個元組內存,t1和t2所指向的內存發生改變。

總結

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

彭泽县| 上栗县| 桐柏县| 高淳县| 体育| 青州市| 博湖县| 莒南县| 清镇市| 丁青县| 清水县| 沙田区| 清新县| 新野县| 龙游县| 格尔木市| 浪卡子县| 万载县| 黄骅市| 遵义县| 慈溪市| 岳普湖县| 厦门市| 吉木乃县| 丰台区| 沈丘县| 凤庆县| 黑龙江省| 广水市| 武威市| 荆州市| 万盛区| 高陵县| 石林| 正宁县| 静海县| 威宁| 车致| 兴仁县| 临沭县| 石城县|