Python共享傳參

函數(shù)的參數(shù)作為引用

Python 唯一支持的參數(shù)傳遞是 共享傳參 ,也就是常說(shuō)的引用傳參。
函數(shù)內(nèi)部的形參是實(shí)參的別名

def f(a, b):
    a += b
    return a
# 數(shù)字,不變
x, y = 1, 2
f(x, y)
print(x, y)

# 列表可變類型,變了
x, y = [1, 2], [3, 4]
f(x, y)
print(x, y)

# 元組不可變類型,不變
x, y = (1, 2), (3, 4)
f(x, y)
print(x, y)
1 2
[1, 2, 3, 4] [3, 4]
(1, 2) (3, 4)

函數(shù)參數(shù)的默認(rèn)值

避免使用可變類型作為參數(shù)的默認(rèn)值

class HauntedBus:
    
    def __init__(self, passengers=[]):
        self.passengers = passengers
        
    def pick(self, name):
        self.passengers.append(name)
        
    def drop(self, name):
        self.passengers.remove(name)
# 給定參數(shù)沒有問題
bus1 = HauntedBus(['Alice', 'Bob'])
print(bus1.passengers)

bus1.pick('Canny')
bus1.drop('Alice')
bus1.passengers
['Alice', 'Bob']
['Bob', 'Canny']
# 使用參數(shù)的默認(rèn)值,即 []
bus2 = HauntedBus()
bus2.pick('David')
bus2.passengers
['David']
# 同樣使用默認(rèn)值,問題就來(lái)了
bus3 = HauntedBus()
bus3.passengers
['David']
bus3.pick('Bruce')
bus2.passengers
['David', 'Bruce']
bus3.passengers is bus2.passengers
True
HauntedBus.__init__.__defaults__
(['David', 'Bruce'],)
HauntedBus.__init__.__defaults__[0] is bus2.passengers
True

bus3 按道理使用的是默認(rèn)值 [],但是得到的確實(shí) bus2 的 passengers 值,而且它們都是同一個(gè)引用。
默認(rèn)值在定義函數(shù)時(shí)計(jì)算,因此默認(rèn)值變成了函數(shù)對(duì)象的屬性。
如果默認(rèn)值是可變對(duì)象,而且修改了它的值,那么后續(xù)的函數(shù)調(diào)用都會(huì)受到影響。

__init__ 方法應(yīng)該這樣處理默認(rèn)值,防御可變參數(shù)

class XXX:
    
    def __init__(self, passengers=None):
        if passengers is None:
            self.passengers = []
        else:
            self.passengers = list(passengers)   # 注意不是直接賦值,而是副本賦值,關(guān)于是深淺拷貝視情況而定
            
    ...

除非確實(shí)是想修改通過參數(shù)傳入的對(duì)象,否則在類中直接把參數(shù)賦值給實(shí)例變量之前一定要想清楚,因?yàn)檫@樣會(huì)為參數(shù)對(duì)象創(chuàng)建別名。

md效果不好,原先是 jupyter notebook 版本

最后編輯于
?著作權(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),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 〇、前言 本文共108張圖,流量黨請(qǐng)慎重! 歷時(shí)1個(gè)半月,我把自己學(xué)習(xí)Python基礎(chǔ)知識(shí)的框架詳細(xì)梳理了一遍。 ...
    Raxxie閱讀 19,589評(píng)論 17 410
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,685評(píng)論 1 51
  • 今天老大學(xué)校舉行了第二屆家長(zhǎng)節(jié),下午早早的出發(fā)了,到了學(xué)校已經(jīng)來(lái)了好多的家長(zhǎng),找到自己的班級(jí)跟其他家長(zhǎng)一起排隊(duì)站好...
    仲昊惟閱讀 264評(píng)論 2 3
  • 方方_d09f閱讀 170評(píng)論 0 0

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