最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python3中函數(shù)參數(shù)傳遞方式實(shí)例詳解

 更新時(shí)間:2019年05月05日 11:50:43   作者:呂歸塵的2018  
這篇文章主要介紹了Python3中函數(shù)參數(shù)傳遞方式,結(jié)合實(shí)例形式較為詳細(xì)的分析了Python3中函數(shù)參數(shù)傳遞的常見(jiàn)操作技巧,需要的朋友可以參考下

本文實(shí)例講述了Python3中函數(shù)參數(shù)傳遞方式。分享給大家供大家參考,具體如下:

之前在看北理工嵩天等老師的python3的課程,在第五周中老師講到了函數(shù)的調(diào)用傳遞。老師講了這樣一個(gè)例子

#處理多個(gè)銀行賬戶的余額信息
def addInterest(balances, rate):
  for i in range(len(balances)):
    balances[i] = balances[i] * (1+rate)
def test():
  amounts = [1000, 105, 3500, 739]
  rate = 0.05
  addInterest(amounts, rate)
  print(amounts)
test()

在這個(gè)例子中可以看到為了處理多個(gè)銀行賬戶設(shè)置了amounts這個(gè)列表,老師的原話是這樣的:

“在test函數(shù)中一開(kāi)始設(shè)置了amounts為4個(gè)值的列表,然后將amounts作為第一個(gè)參數(shù)傳遞給函數(shù)addInterest,并調(diào)用執(zhí)行該函數(shù),最后打印輸出amounts的結(jié)果,運(yùn)行結(jié)果如下:

[1050.0,110.25,3675.0,775.95]


然后禮欣老師得出結(jié)論,以下為原話

“在這個(gè)例子中可以看到,amounts變量的值好像是被修改了,但是函數(shù)是不能改變變量本身即amounts的”

接下來(lái)是分析下函數(shù)的執(zhí)行過(guò)程,過(guò)程如下圖

分析原話如下

“接下來(lái)分析下整個(gè)執(zhí)行過(guò)程,查看amounts輸出結(jié)果是如何發(fā)生變化的。首先函數(shù)test的前兩條語(yǔ)句建立了兩個(gè)變量amounts和rate,然后控制傳遞給addinterest,這里amounts是一個(gè)包含4個(gè)整數(shù)類(lèi)型值的列表對(duì)象,以實(shí)參的形式傳遞給函數(shù)addinterest形參balances,下一步執(zhí)行函數(shù)addinterest,從0到length-1范圍執(zhí)行循環(huán),并更新balances的值?!?/p>

重點(diǎn)來(lái)了:原話如下

“圖中舊值 [1000, 105, 3500, 739]
并沒(méi)有改變,只是Python又創(chuàng)建了一組新值[1050.0,110.25,3675.0,775.95]
,并且使列表對(duì)象指向該組新值,而舊值會(huì)在Python的垃圾數(shù)據(jù)回收的時(shí)候被清除掉③,從圖中我們可以清楚的看出,為什么包含列表參數(shù)的程序addinterest修改了列表的值?但程序addinterest結(jié)束時(shí)存儲(chǔ)在amounts中的是新balances的值,實(shí)際上變量amounts從來(lái)沒(méi)有被改變過(guò)?!?br /> “它(amounts,作者注)仍然指向的是調(diào)用addinterest函數(shù)之前的同一個(gè)列表,只是當(dāng)控制返回到調(diào)用函數(shù)中時(shí),列表呈現(xiàn)了被修改的狀態(tài)”②

最后是得出結(jié)論,原話如下:

“通過(guò)上述過(guò)程我們可以了解到:Python的參數(shù)是通過(guò)值來(lái)傳遞的。但是如果變量是可變對(duì)象,比如是列表或者是圖形對(duì)象,返回到調(diào)用程序后,該對(duì)象會(huì)呈現(xiàn)出被修改的狀態(tài)?!?/p>

^_^
注:課程原始視頻部分結(jié)束。

看了老師的這段講解之后產(chǎn)生了很多疑問(wèn):在前面(①處)講的amounts是不能被修改的,但是在(②處)又說(shuō)列表呈現(xiàn)了被修改的狀態(tài),這不是自相矛盾嗎?在(③)處講列表創(chuàng)建了新值并且使列表指向了新值,這里不就是說(shuō)amounts發(fā)生了改變嗎?怎么能說(shuō)沒(méi)變呢?最后結(jié)論也是列表呈現(xiàn)出了被修改的狀態(tài)。這個(gè)結(jié)論云山霧繞,看得人似懂非懂。

那在Python3中參數(shù)變量是列表,在調(diào)用函數(shù)完返回后到底是被修改了還是沒(méi)被修改呢?

為了弄清這個(gè)問(wèn)題,我做了一個(gè)實(shí)驗(yàn),id()可以查看變量在內(nèi)存中的地址,這個(gè)值相當(dāng)于一個(gè)對(duì)象的“身份證”。

# 處理多個(gè)銀行賬戶的余額信息
def addInterest(balances, rates):
print()
print("第二處", id(balances))
  for i in range(len(balances)):
    balances[i]= balances[i]*(1+rates)
    print()
    print("第三處",id(balances))
def test():
  amounts = [1000,105,3500,739]
  print()
  print("第一處",id(amounts))
  rate = 0.05
  addInterest(amounts, rate)
  print()
  print(amounts)
  print()
  print("第四處",id(amounts))
test()

輸出結(jié)果:

第一處 41203656

第二處 41203656

第三處 41203656

第三處 41203656

第三處 41203656

第三處 41203656

[1050.0, 110.25, 3675.0, 775.95]

第四處 41203656

在這個(gè)實(shí)驗(yàn)中可以清楚的看到,amounts這個(gè)對(duì)象的身份證號(hào)碼在整個(gè)程序運(yùn)行過(guò)程中從未變過(guò),而非視頻中老師講的創(chuàng)建了新的列表對(duì)象。所以amounts作為一個(gè)列表對(duì)象在程序運(yùn)行過(guò)程中是被直接修改了,是的就是直接被修改了,而非指向新balances的值。為什么可以得出這一結(jié)論?我們可以看下第一、三處的id,在未進(jìn)入函數(shù)之前id是41203656(第一處),進(jìn)入函數(shù)之后對(duì)象id仍然未變,函數(shù)運(yùn)行完返回之后對(duì)象id仍然未變!

所以結(jié)論應(yīng)該這樣寫(xiě)會(huì)比較清楚:

改變參數(shù)值值的函數(shù):
實(shí)參傳給形參時(shí),python的參數(shù)是通過(guò)值來(lái)傳遞的;
如果變量是可變對(duì)象(如列表或者圖形對(duì)象),該對(duì)象會(huì)在函數(shù)中會(huì)被直接修改,返回到調(diào)用程序后也是被修改后的狀態(tài)。

那是不是Python3中函數(shù)都是像這種傳遞方式呢?我們對(duì)課程視頻中的另一個(gè)例子做一個(gè)簡(jiǎn)單的修改。

 # 計(jì)算單個(gè)銀行賬戶余額
def addinterest(balance, rate):
  print("第二處", id(balance))
  newBalance = balance * (1 + rate)
  print()
  print("第三處", id(balance))
  print()
  print("第四處", id(newBalance))
  return newBalance
def main():
  amount = 1000
  print("第一處", id(amount))
  print()
  rate = 0.05
  amount = addinterest(amount, rate)
  print()
  print("第五處", id(amount))
  print()
  print(amount)
  print("第六處", id(amount))
main()

運(yùn)行結(jié)果如下:

第一處 33533648

第二處 33533648

第三處 33533648

第四處 33563344

第五處 33563344

1050.0
第六處 33563344

不是說(shuō)好的直接修改的嗎?怎么身份證又變了?其實(shí)這里的對(duì)象amount是個(gè)常數(shù),即為不可變對(duì)象,當(dāng)在函數(shù)中要對(duì)對(duì)象進(jìn)行處理時(shí),由于對(duì)象不可變,只能新建一個(gè)新對(duì)象,然后return出新的對(duì)象了。

這個(gè)也就是目前網(wǎng)絡(luò)上大部分博客的結(jié)論:

1、不可變對(duì)象作為函數(shù)參數(shù),Python通過(guò)值傳遞;
2、 可變對(duì)象作為函數(shù)參數(shù),Python通過(guò)引用傳遞。

注:Python中,數(shù)值類(lèi)型(int和float)、字符串str、元組tuple都是不可變類(lèi)型。而列表list、字典dict、集合set是可變類(lèi)型。
(但是也有博客把這兩個(gè)結(jié)論搞反了)

但是也有博客提出了一個(gè)類(lèi)似這樣的例子

def change(val):
  val = val + [10]
nums = [0, 1]
change(nums)
print(nums)

輸出結(jié)果為

[0, 1]

其實(shí)這里是寫(xiě)的不嚴(yán)謹(jǐn),不能直接用加號(hào)添加列表元素
可以改為這樣

def change(val):
  newval = [10]
  val= val + newval
nums = [0, 1]
change(nums)
print(nums)

但是輸出結(jié)果還是

[0, 1]

難道上面的結(jié)論不對(duì)嗎?

其實(shí)這里要補(bǔ)充另外一種情況:對(duì)于可變對(duì)象作為函數(shù)參數(shù),且參數(shù)不指向其他對(duì)象時(shí),相當(dāng)于引用傳遞;否則,若參數(shù)指向其他對(duì)象,則對(duì)參數(shù)變量的操作并不影響原變量的對(duì)象值

函數(shù)里的參數(shù)變量val指向了與nums不同的內(nèi)存變量,所以函數(shù)里的參數(shù)變量val不影響原變量nums的值

**這也是因?yàn)閜ython的特性” 變量無(wú)類(lèi)型,對(duì)象有類(lèi)型 “。
變量是對(duì)內(nèi)存空間的引用,當(dāng)參數(shù)變量和原變量指向不同的內(nèi)存空間時(shí),操作互不影響。**

用下面這個(gè)看下

def change(val):
  newval = [10]
  print("第二處",id(val))
  val = val + newval
  print("第三處",id(val))
nums = [0, 1]
print("第一處",id(nums))
change(nums)
print("第四處",id(nums))
print(nums)

運(yùn)行結(jié)果如下:

第一處 39695944
第二處 39695944
第三處 39710024
第四處 39695944
[0, 1]

可以看到第一處的nums和第二處的val的內(nèi)存地址完全一樣,然后執(zhí)行到第三處時(shí),由于函數(shù)內(nèi)VAL重新指向了別的內(nèi)存變量,所以內(nèi)存地址不同。但是最后結(jié)果要輸出變量nums,即第一處第二處內(nèi)存地址的值,所以和第三處的val就沒(méi)關(guān)系了。其實(shí)這里的val是沒(méi)有返回值的。

想要直接在列表中添加元素可以寫(xiě)成這樣:

def change(val):
  val.append(10)
nums = [0, 1]
change(nums)
print(nums)

輸出結(jié)果是

[0, 1, 10]

關(guān)于變量無(wú)類(lèi)型,對(duì)象有類(lèi)型可以這樣理解:只有放在內(nèi)存空間中的對(duì)象(也就是數(shù)據(jù))才有類(lèi)型,而變量是沒(méi)有類(lèi)型的。

如果還是不明白可以做這樣一種比喻:變量就好比釣魚(yú)者,湖水就好像內(nèi)存,里面有各種各樣的魚(yú),它們就是對(duì)象。釣魚(yú)者(變量)的任務(wù)就是用某種方式把自己和魚(yú)(對(duì)象)通過(guò)魚(yú)線連接起來(lái)。那么,魚(yú)(對(duì)象)是有類(lèi)型的,有鰱魚(yú)、鯽魚(yú)、帶魚(yú)。釣魚(yú)者(變量)沒(méi)有類(lèi)型,他釣到不同類(lèi)型的魚(yú)(對(duì)象)。

用釣魚(yú)的比喻解釋下上面的例子

def change(val):
  newval = [10]
  val= val + newval
nums = [0, 1]
change(nums)
print(nums)

1、釣魚(yú)人已經(jīng)釣了一桶魚(yú)用nums桶裝著,nums桶可以裝很多魚(yú)。

2、現(xiàn)在提著這個(gè)nums桶繼續(xù)在湖里釣魚(yú),這時(shí)候nums桶暫時(shí)叫做裝魚(yú)桶val,突然釣魚(yú)人釣了一條大魚(yú),發(fā)現(xiàn)裝魚(yú)桶val裝不下,于是釣魚(yú)人又在漁具店買(mǎi)了另一個(gè)大的裝魚(yú)桶VAL,把大魚(yú)和之前的魚(yú)一塊裝了。
釣魚(yú)活動(dòng)結(jié)束。

3、最后要看看那個(gè)叫nums的桶有哪些魚(yú),這時(shí)候當(dāng)然只能看之前的情況。

即這個(gè)結(jié)論:對(duì)于可變對(duì)象作為函數(shù)參數(shù),且參數(shù)不指向其他對(duì)象時(shí),相當(dāng)于引用傳遞;否則,若參數(shù)指向其他對(duì)象,則對(duì)參數(shù)變量的操作并不影響原變量的對(duì)象值。

同樣的針對(duì)其他兩個(gè)結(jié)論,也可以用這個(gè)比喻解釋?zhuān)?/p>

def change( val):
  newval = val + 10
  return newval
num = 1
num = change(num)
print(num)

1、釣魚(yú)人手上的東西num是個(gè)小蚯蚓。

2、釣魚(yú)人拿著num去湖邊釣魚(yú),小蚯蚓被大魚(yú)吃了,釣魚(yú)人釣到了一條大魚(yú),釣魚(yú)人拿著魚(yú)回家。
釣魚(yú)活動(dòng)結(jié)束。

3、問(wèn)釣魚(yú)人手上現(xiàn)在拿著什么東西num?當(dāng)然是一條大魚(yú)。

def change(val):
  val.append(10)
nums = [0, 1]
change(nums)
print(nums)

1、釣魚(yú)人提著一個(gè)叫nums的桶,桶里裝著2條魚(yú)

2、釣魚(yú)人來(lái)到湖邊釣魚(yú),此時(shí)桶暫時(shí)叫裝魚(yú)桶val,釣魚(yú)人釣到了一條魚(yú)放進(jìn)裝魚(yú)桶val。
釣魚(yú)活動(dòng)結(jié)束。

3、看看釣魚(yú)人桶里的有幾條魚(yú)。

總結(jié)來(lái)說(shuō):

**對(duì)于不可變對(duì)象作為函數(shù)參數(shù),相當(dāng)于C系語(yǔ)言的值傳遞;
對(duì)于可變對(duì)象作為函數(shù)參數(shù),且參數(shù)不指向其他對(duì)象時(shí),相當(dāng)于C系語(yǔ)言的引用傳遞。
對(duì)于可變對(duì)象作為函數(shù)參數(shù),參數(shù)指向其他對(duì)象,對(duì)參數(shù)變量的操作不影響原變量的值。**

關(guān)于Python相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《Python函數(shù)使用技巧總結(jié)》、《Python面向?qū)ο蟪绦蛟O(shè)計(jì)入門(mén)與進(jìn)階教程》、《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python字符串操作技巧匯總》、《Python編碼操作技巧總結(jié)》及《Python入門(mén)與進(jìn)階經(jīng)典教程

希望本文所述對(duì)大家Python程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • Win10?Anaconda?新建環(huán)境安裝python-pcl的步驟

    Win10?Anaconda?新建環(huán)境安裝python-pcl的步驟

    這篇文章主要介紹了Win10?Anaconda?新建環(huán)境安裝python-pcl的方法,至于VS環(huán)境下安裝C++?版本的pcl也可以按照此文提供的步驟安裝實(shí)現(xiàn),需要的朋友可以參考下
    2022-04-04
  • Python?Pandas的concat合并

    Python?Pandas的concat合并

    這篇文章主要介紹了Python?Pandas的concat合并,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-08-08
  • Python3通過(guò)chmod修改目錄或文件權(quán)限的方法示例

    Python3通過(guò)chmod修改目錄或文件權(quán)限的方法示例

    這篇文章主要介紹了Python3通過(guò)chmod修改目錄或文件權(quán)限的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • Python處理Excel的14個(gè)常用操作總結(jié)

    Python處理Excel的14個(gè)常用操作總結(jié)

    在數(shù)據(jù)處理和分析的領(lǐng)域中,Excel是一種被廣泛使用的工具,然而,通過(guò)Python處理Excel,能夠更好地實(shí)現(xiàn)自動(dòng)化和批量處理,本文為大家整理了14個(gè)Python處理Excel的常用操作,希望對(duì)大家有所幫助
    2023-12-12
  • Python閉包技巧介紹

    Python閉包技巧介紹

    這篇文章主要介紹了Python閉包,所謂閉包就是用函數(shù)代替類(lèi),被外層函數(shù)包圍的內(nèi)層函數(shù),它能夠獲取外層函數(shù)范圍中的變量,感興趣的小伙伴請(qǐng)和小編一起進(jìn)入文章學(xué)習(xí)具體內(nèi)容吧
    2021-12-12
  • Python實(shí)現(xiàn)二叉樹(shù)的常見(jiàn)遍歷操作總結(jié)【7種方法】

    Python實(shí)現(xiàn)二叉樹(shù)的常見(jiàn)遍歷操作總結(jié)【7種方法】

    這篇文章主要介紹了Python實(shí)現(xiàn)二叉樹(shù)的常見(jiàn)遍歷操作,結(jié)合實(shí)例形式總結(jié)分析了二叉樹(shù)的前序、中序、后序、層次遍歷中的迭代與遞歸等7種操作方法,需要的朋友可以參考下
    2019-03-03
  • 最新評(píng)論

    广西| 安泽县| 栖霞市| 潍坊市| 白城市| 安平县| 仙游县| 黄平县| 扶风县| 谢通门县| 颍上县| 淅川县| 丹寨县| 鄯善县| 福鼎市| 荥经县| 广丰县| 武汉市| 凤台县| 惠安县| 牙克石市| 封丘县| 商都县| 大厂| 巴林右旗| 贵阳市| 枣庄市| 邯郸县| 南召县| 平潭县| 合水县| 江山市| 富平县| 常山县| 天等县| 保德县| 渑池县| 梁河县| 阜宁县| 岑溪市| 阿合奇县|