參考:
先說一下預設引數
當我們呼叫乙個函式的時候,忘記傳入相應的引數了,那麼函式肯定呼叫失敗。為了讓函式可以在「失誤」的情況下也可以呼叫出來,那麼預設引數就可以派上用場了。
例如,計算x2
,可以完全把第二個引數值設為預設引數。
def
power
(x, n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
當我們呼叫power(3)的時候,相當於是在呼叫power(3, 2)。而對於想要計算高階,那麼就必須傳入第二個引數了,如power(3, 3)。
在設定預設引數的時候,需要注意以下幾點:
1. 必選引數在前,預設引數在後面。要是預設引數設定在前面,你懂得,還是會報傳參錯誤的。
2. 當函式有多個引數的時候,把變化大的引數放在前面,變化小的引數放在後面,變化小的引數就可以作為預設引數。
使用預設引數的目的就是為了降低呼叫函式的難度。
預設引數使用的時候,廖大這邊介紹了乙個坑,目的是為了說明:預設引數必須指向不變的物件。
for example
定義乙個函式,傳入乙個list,新增乙個end再返回:
def
add_end
(l=):
return l
當正常呼叫的時候不會出錯:
>>> add_end([1, 2, 3])
[1, 2, 3, 'end']
>>> add_end(['x', 'y', 'z'])
['x', 'y', 'z', 'end']
當使用預設引數的時候,一開始似乎是對的:
>>> add_end()
['end']
但是,再次呼叫的時候,就不對了:
>>> add_end()
['end', 'end']
>>> add_end()
['end', 'end', 'end']
似乎每次呼叫的時候都記住了之前傳入的這個end。怎麼肥四?
其實,原因在於函式定義的時候,預設引數l的值就已經被計算出來了,也就是[ ],因為預設引數l也是乙個變數,它指向了物件[ ]。每次呼叫函式的時候,如果改變了l的內容,要是下次再次呼叫的時候,預設引數的內容也跟著改變了,不再是當時定義的[ ]了。
要規避上述的問題,可以用不可變的物件來實現,如none
def
add_end
(l=none):
if l is
none:
l =
return l
下次再次呼叫的時候,就不會有問題了:
>>> add_end()
['end']
>>> add_end()
['end']
預設引數是為了減少我們傳入的引數,要是,我們知道需要對函式傳入引數,但是,不知道會傳幾個,有時候可能要傳2個,有時候3個,有時候100個呢?總不可能對於每乙個需求都寫乙個函式吧?況且這些函式內部都是相似的。
怎麼辦?
我們如果可以傳入乙個可伸縮的引數個數就完美了。
for example
我們以數學題為例子,給定一組數字a,b,c……,請計算a2
+b2+
c2+…
… 。
要定義出這個函式,我們必須確定輸入的引數。由於引數個數不確定,我們首先想到可以把a,b,c……作為乙個list或tuple傳進來,這樣,函式可以定義如下:
def
calc
(numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
那麼在呼叫的時候可以先組裝乙個list或者tuple傳入。
>>> calc([1, 2, 3])
14>>> calc((1, 3, 5, 7))
84
那麼,可不可以不組裝,直接傳入1,2,3呢?
我們可以這麼做:
def
calc
(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
在引數前面加乙個*,表示引數numbers接收到的是乙個tuple,因此,函式**完全不變。但是,呼叫該函式時,可以傳入任意個引數,包括0個引數。
>>> calc(1, 2)
5>>> calc()
0
如果我們已經有了乙個list或者tuple,需要傳入的話可以這麼做:
>>> nums = [1, 2, 3]
>>> calc(*nums)
14
只需要在這個list或者tuple前面加乙個*就ok了。
現在我們可以把多個引數組裝成乙個list或者tuple並且用帶*的形式傳入了,但是,如果我們要傳入帶名字的引數呢?類似於要傳入bobo = superman。怎麼辦?
這時我們可以用帶兩個**的形式傳入。
for example
def
person
(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
我們可以只傳入name和age:
>> person('michael', 30)
name: michael age: 30 other: {}
除了name和age之外,還可以傳入關鍵字引數kw
>>> person('bob', 35, city='beijing')
name: bob age: 35 other:
函式的引數
沒有引數 定義函式和呼叫函式時括號裡都不寫內容 2.有乙個引數 傳什麼就是什麼 3.有多個引數 站在實參的角度上 按位置傳參 按關鍵字傳參 混著用可以 但是必須先按照位置傳參,再按照關鍵字傳參。不能給同乙個變數傳多個值。站在形參的角度上 位置引數 必須傳,且有幾個引數就傳幾個值 預設引數 可以不傳,...
函式的引數
現在,我們已經把函式返回值相關的事情研究清楚了,我們自己已經完成了乙個可以返回字串長度的函式。但是現在這個函式還是不完美,之前我們使用len函式的時候得是length len hello world 這樣我可以想計算誰就計算誰的長度。但是現在我們寫的這個函式,只能計算乙個 hello world 的...
函式的引數
函式的引數有實參和形參 形參可以當作區域性變數 本質上是將實參賦值給形參 傳遞物件時,相當於obj person,引用型別賦值的是位址,儲存在堆記憶體中,指向同乙個物件,person對多乙個name var person function setperson obj setperson person...