Python進階:值傳遞,引用傳遞?不存在的,是賦值傳遞

Python的變量及其賦值

  c/c++/c#/java 裏面都有值傳遞,引用傳遞的概念,在Python中是如何的?
  例
a = 1
b = a
print(id(a),id(b)) #140723344823328 140723344823328
  此時,變量a與變量b指向同一對象
  變量的賦值,只是表示讓變量指向了某個對象,並不表示拷貝對象給變量;而一個對象,能夠被多個變量所指向。
  
  接着
a = a + 1
print(b) #1
  因爲整型變量(int),字符串(string)都是不可類型,a = a + 1 會建立一個值爲2的新對象,並用a指向它。
  所以,b指向的仍是1這個對象。 【對於不可變對象(字符串,整型,元祖等等),全部指向該對象的變量的值老是同樣的,也不會改變。可是經過某些操做(+= 等等)更新不可變對象的值時,會返回一個新的對象。】
  

  列表的例子

  可變對象(列表,字典,集合等等)的改變,會影響全部指向該對象的變量。
l1 = [1, 2, 3]
l2 = l1
l1.append(4)
print(l1) #[1, 2, 3, 4]
print(l2) #[1, 2, 3, 4]

  因爲l1是可變類型,所以l1.append(4)不會建立新對象,會在原列表中插入4,而l1與l2都是指向這個列表,因此值都爲[1,2,3,4]java

  

  變量能夠刪除,但對象沒法被刪除。
l = [1, 2, 3]
del l #l被刪除,對象[1,2,3]仍然存在

Python 函數的參數傳遞

  1)c++

def my_func1(b):
    b = 2

a = 1
my_func1(a)
print(a) #1

  這裏參數傳遞後 b與a 同時指向 值爲1這個對象,接着b=2,系統創建2這個對象,並把b指向2,所以a仍是指向值爲1的對象c#

  2) return讓 a 指向 b指向的 值爲2的對象
def my_func2(b):
    b = 2
    return b

a = 1
a = my_func2(a)
print(a) #2

  3)app

def my_func3(l2):
    l2.append(4)

l1 = [1, 2, 3]
my_func3(l1)
print(l1) #[1, 2, 3, 4]
  l2與l1都指向[1,2,3]這個列表對象,列表是可變類型,列表對象的值修改後並不會從新建立一個新對象,指向這個對象的l1的值也相應變爲[1,2,3,4]
  4)
def my_func4(l2):
    l2 = l2 + [4]

l1 = [1, 2, 3]
my_func4(l1)
print(l1)#[1, 2, 3]

  l2=l2+[4] 會建立一個新的列表對象[1,2,3,4]並把l2指向這個新對象,所以l1不會受影響函數

  5)
  若是想把l1也指向新對象,則能夠用return
def my_func5(l2):
    l2 = l2 + [4]
    return l2

l1 = [1, 2, 3]
l1 = my_func5(l1)
print(l1) #[1, 2, 3, 4]

  第3)與第5的做用是同樣的,但實際中通常會使用return語句,語義會更加清晰spa

總結

  • Python中參數的傳遞既不是值傳遞,也不是引用傳遞,而是賦值傳遞,或者是叫對象的引用傳遞,指向一個具體的對象
  • 若是對象是可變的,當其改變時,全部指向這個對象的變量都會改變。
  • 若是對象不可變,簡單的賦值只能改變其中一個變量的值,其他變量則不受影響。

 參考

  極客時間 《Python核心技術與實戰》專欄code

相關文章
相關標籤/搜索