Python初學(xué)者筆記(八):函數(shù)參數(shù)的值傳遞和引用傳遞

函數(shù)參數(shù)的值傳遞和引用傳遞

像我們最熟悉的 C 語言,再寫函數(shù)參數(shù)的同時(shí)需要規(guī)定函數(shù)參數(shù)到底是值傳遞還是引用傳遞。引用傳遞導(dǎo)致該參數(shù)在函數(shù)內(nèi)的修改出了函數(shù)之外也會(huì)生效,值傳遞所有的修改都不會(huì)體現(xiàn)到函數(shù)外部。

Python 稍微有一點(diǎn)特殊,在定義函數(shù)的時(shí)候不允許選擇參數(shù)的傳遞的方式,傳遞方式只與參數(shù)的數(shù)據(jù)類型有關(guān)。

Python 有 6 中標(biāo)準(zhǔn)的數(shù)據(jù)類型:Number,String,List,Tuple,Set,Dictionary。不可變數(shù)據(jù)(3 個(gè)):Number(數(shù)字)、String(字符串)、Tuple(元組);可變數(shù)據(jù)(3 個(gè)):List(列表)、Dictionary(字典)、Set(集合)。再加上自定義對(duì)象,共 7 種數(shù)據(jù)類型。

其中不可變數(shù)據(jù)(Number,String,Tuple)為值傳遞,可變數(shù)據(jù)(List,Dictionary,Set)和自定義對(duì)象為引用傳遞。

舉幾個(gè)例子就明白了。

Number 值傳遞

Number 又包含 int、float、bool、complex。

for i in [0,1.2,True,4+3j]:
    print("**--------**")
    print(i)
    def testint(i):
        i = 0
    testint(i)
    print(i)

    j = i
    j = 0
    print(i,j)

輸出:

**--------**
0
0
0 0
**--------**
1.2
1.2
1.2 0
**--------**
True
True
True 0
**--------**
(4+3j)
(4+3j)
(4+3j) 0
  1. 函數(shù)內(nèi)的參數(shù)值的改變不會(huì)影響到外部

  2. 把 i 用 = 賦值給 j,i 和 j 互不影響

String 值傳遞

和 Number 一樣:

  1. 函數(shù)內(nèi)的參數(shù)值的改變不會(huì)影響到外部

  2. 把 i 用 = 賦值給 j,i 和 j 互不影響

for i in ["11","abc"]:
    print("**--------**")
    print(i)
    def testint(i):
        i = "www"
    testint(i)
    print(i)

    j = i
    j = "555"
    print(i,j)
**--------**
11
11
11 555
**--------**
abc
abc
abc 555

Tuple 值傳遞

用的很少,不舉例子嘍。

List 引用傳遞

  1. 函數(shù)內(nèi)的參數(shù)值的改變會(huì)影響到外部

  2. 把 i 用 = 賦值給 j,對(duì) j 進(jìn)行除新賦值之外的任何操作都會(huì)影響到 i

  3. 把 j 賦值成另外的值并不會(huì)導(dǎo)致 i 也變成同樣的值

l = [1,2,3,4,5,6]
print("**--------**")
print(l)
def testint(l):
    l.pop()
testint(l)
print(l)

j = l
j.pop()
print(l,j)
j = ["555","666"]
print(l,j)

Dictionary 引用傳遞

  1. 函數(shù)內(nèi)的參數(shù)值的改變會(huì)影響到外部

  2. 把 i 用 = 賦值給 j,對(duì) j 進(jìn)行除新賦值之外的任何操作都會(huì)影響到 i

  3. 把 j 賦值成另外的值并不會(huì)導(dǎo)致 i 也變成同樣的值

l = dict()
l[1] = 1
l[2] = 2
print("**--------**")
print(l)
def testint(l):
    l.pop(1)
testint(l)
print(l)

j = l
j.pop(2)
print(l,j)
j = ["555","666"]
print(l,j)

Set 引用傳遞

  1. 函數(shù)內(nèi)的參數(shù)值的改變會(huì)影響到外部

  2. 把 i 用 = 賦值給 j,對(duì) j 進(jìn)行除新賦值之外的任何操作都會(huì)影響到 i

  3. 把 j 賦值成另外的值并不會(huì)導(dǎo)致 i 也變成同樣的值

l = set()
l.add(1)
l.add(2)
print("**--------**")
print(l)
def testint(l):
    l.remove(1)
testint(l)
print(l)

j = l
j.remove(2)
print(l,j)
j = ["555","666"]
print(l,j)

自定義對(duì)象 引用傳遞

將自定義對(duì)象或?qū)⒆远x對(duì)象封裝在 List/Tuple 種作為參數(shù):

  1. 函數(shù)內(nèi)的參數(shù)值的改變會(huì)影響到外部

  2. 把 i 用 = 賦值給 j,對(duì) j 進(jìn)行除新賦值之外的任何操作都會(huì)影響到 i

  3. 把 j 賦值成另外的值并不會(huì)導(dǎo)致 i 也變成同樣的值

class Node:
    def __init__(self, val = 0, neighbors = []):
        self.val = val
        self.neighbors = neighbors

n1 = Node(1)
n2 = Node(2)
nl = [n1,n2]
print(nl[0].val)
def t22(nodeList):
    nodeList[0].val = 0
t22(nl)
print(nl[0].val)

def t222(node):
    node.val = 0

print(n2.val)
t222(n2)
print(n2.val)
  • tips

    當(dāng)自定義類的屬性有引用傳遞對(duì)象時(shí),需要將該引用傳遞對(duì)象 copy 一下再傳入自定義對(duì)象。

class Node:
    def __init__(self, val = 0, neighbors = []):
        self.val = val
        self.neighbors = neighbors

l = [1,2,3,4]
n1 = Node(1,l)
n2 = Node(2,l)
nl = (n1,n2)
print(nl[0].neighbors,nl[1].neighbors,l)
def t22(nodeList):
    nodeList[0].neighbors.pop()
t22(nl)
print(nl[0].neighbors,nl[1].neighbors,l)
print(l)

print("---------")
n1 = Node(1,l.copy())
n2 = Node(2,l.copy())
nl = (n1,n2)
print(nl[0].neighbors,nl[1].neighbors,l)
def t22(nodeList):
    nodeList[0].neighbors.pop()
t22(nl)
print(nl[0].neighbors,nl[1].neighbors,l)
print(l)

輸出:

[1, 2, 3, 4] [1, 2, 3, 4] [1, 2, 3, 4]
[1, 2, 3] [1, 2, 3] [1, 2, 3]
[1, 2, 3]
---------
[1, 2, 3] [1, 2, 3] [1, 2, 3]
[1, 2] [1, 2, 3] [1, 2, 3]
[1, 2, 3]
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容