1. 程式人生 > >python的函式——進階(打包與拆包、不定長引數、預設引數)

python的函式——進階(打包與拆包、不定長引數、預設引數)

整體:

1. 函式的返回值的打包與拆包

2. 為函式的引數設定預設值

3. 函式引數的打包與拆包

----函式返回值的打包

def 函式名(引數列表):

函式體執行內容

return 返回值1,返回值2,返回值3,...

此時呼叫函式時,變數 = 函式名(傳參),變數得到的是一個打包後返回值的元祖型別資料,元祖內包含了所有返回值

函式的返回值可以是Python的所以型別資料,包括字串,數值,None,列表,元祖,字典,物件等


>>> def dest(a,b,c,d):
	print("傳入的值,a:%s,b:%s,c:%s,d:%s" % (a,b,c,d))
	return a,b,c,d

#dest(1,2,3,4),函式被呼叫,執行了函式體,所以列印輸出了資料
>>> var = dest(1,2,3,4)
傳入的值,a:1,b:2,c:3,d:4

#var儲存了dest函式的返回值
>>> var
(1, 2, 3, 4)      #預設打包返回一個元祖


#使用列表
>>> def dest1(a,b,c,d):
	return [a,b,c,d]

>>> var1 = dest1(1,2,3,4)
>>> var1
[1, 2, 3, 4]       #返回了一個列表
>>> 

函式返回多個值時,預設打包成一個元祖,雖然沒有用()包裹,可以理解成一個變異元祖,除了沒有括號包裹,其它都一樣

注意:當多個值時,因為預設是返回一個元祖,所以當多個值時不可以再使用()包裹,包裹會報錯

預設返回元祖的形式,但是可以使用[ ]包裹,會進行打包返回一個列表形式的資料

 

----函式返回值的拆包

def 函式名(引數列表):

函式體執行內容

return 返回值1,返回值2,返回值3,...

變數1,變數2,變數3,... = 函式名(引數列表)

使用多個變數進行接收資料就可以進行返回值的拆包

>>> def dest2(a,b,c,d):
	return a,b,c,d

#一個變數接收多個返回值,會被自動打包成一個元祖型別的資料
>>> var = dest2(1,2,3,4)
>>> var
(1, 2, 3, 4)

#使用多個變數與返回值一一對應接收,返回值資料會被拆包,對變數進行一一賦值
>>> var1,var2,var3,var4 = dest2(1,2,3,4)
>>> var1
1
>>> var2
2
>>> var3
3
>>> var4
4
>>> 

注意:變數需要與返回值一 一對應,數量量不能出現錯誤,否則會報錯

 


 

----為函式引數設定預設值

def 函式名(普通引數,預設引數=預設值)

注意:預設引數要放在所有的普通引數後面

定義函式時,可以給一個引數設定一個預設值,當該引數沒有被傳參時,函式體內使用預設值參與計算

>>> def dest(name,age,sex='保密'):
	print("姓名:%s,性別:%s,年齡:%s"%(name,sex,age))

#預設引數不傳入資料,會使用預設值
>>> dest('小明',18)
姓名:小明,性別:保密,年齡:18

#傳入值時,會使用傳入的資料
>>> dest('小藍',18,'女')
姓名:小藍,性別:女,年齡:18
>>> 

 

 

注意:預設值不要設定成可變型別,因為函式定義後只會被初始化一次,預設值是該函式共享的

>>> def dest(a,b=[]):
	b.append(a)
	print(b)

#呼叫同一個函式傳入同樣的引數,執行結果卻不一樣
>>> dest(1)
[1]
>>> dest(1)
[1, 1]
>>> dest(3)
[1, 1, 3]

 

如果是可變型別的資料,將可能會被函式呼叫發生修改,出現不符合預期的結果

 

----函式傳參時的打包

區別 :*不定長引數可以接收單一的元素,將所有的值進行打包成一個元祖給函式內使用

            **不定長引數是接收鍵值對,將所有的鍵值對打包成一個字典給函式內使用

def 函式名(普通引數,*不定長引數)

定義一個函式時,需要傳入引數長度不固定時可以使用不定長引數,此時傳入的單一值,都會被打包成一個元祖,供函式體內使用

>>> def dest(a,*arge):
	print("a:%s,arge:%s"%(a,arge))

>>> dest(1,'s',(1,2,3,4),[1,2,3,4],'測試',1,2,34,{'name':'小明','age':18},' 所有資料')
#列印結果
a:1,arge:('s', (1, 2, 3, 4), [1, 2, 3, 4], '測試', 1, 2, 34, {'name': '小明', 'age': 18}, ' 所有資料')

#第一個變數直接接收一個數據,其它的資料全部被打包成一個元祖被*arge接收

def  函式名(普通引數,**不定長引數)

定義一個函式時,需要傳入引數長度不固定時可以使用不定長引數,此時傳入的鍵值對,都會被打包成一個字典,供函式體內使用

>>> def dest(a,*arge,**kwarges):
	print("a:",a)
	print('arge:',arge)
	print('kwarges:',kwarges)

#對比,*不定長只接受單一的值,而**不定長是進行接收鍵值對
>>> dest(1,2,3,45,'a',(1,2,3),[1,6,8],name="小明",age=18,sex="男")
a: 1
arge: (2, 3, 45, 'a', (1, 2, 3), [1, 6, 8])
kwarges: {'name': '小明', 'age': 18, 'sex': '男'}

注意:

當出現*不定長引數時,預設引數必須放在*不定長引數的最後,這是語法規定,不必過多糾結

當出現**不定長引數時,預設引數必須放在**不定長引數的前面,,。

當出現*不定長和**不定長時,引數列表順序為:def 函式名(普通引數,*不定長引數 ,預設引數=預設值,**不定長引數)

 

----函式傳參時的拆包

當需要將一組資料傳入函式內使用時,可以使用*拆包,將一組資料拆分成一個個引數

>>> def dest1(a,*arge):
	print("a:",a)
	print("arge:",arge)

#定義一個列表資料 
>>> a = [1,2,3,4]

#將多個列表作為引數傳入
>>> dest1(a,a,a,a)
a: [1, 2, 3, 4]
arge: ([1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4])   #每一個列表被當做一個元素打包到元祖中

#傳參時使用*拆包,列表中的元素被取出,每一個元素單獨作為一個引數傳入
>>> dest1(a,*a)
a: [1, 2, 3, 4]
arge: (1, 2, 3, 4)

#對比上面一下
>>> dest1(a,a)
a: [1, 2, 3, 4]
arge: ([1, 2, 3, 4],)
>>> 

函式內使用不定長時,也可以在函式內進行拆包使用

>>> a = [90,87,67,92,76,80]

>>> def dest(a,*arge):
	print("a:",a)
	print("arge:",arge)
	print("*arge",*arge)

>>> dest(1,a,a)
a: 1
arge: ([90, 87, 67, 92, 76, 80],[90, 87, 67, 92, 76, 80])
*arge [90, 87, 67, 92, 76, 80] [90, 87, 67, 92, 76, 80]

**是將字典拆成鍵值對,使用*對字典拆包只會獲得字典的所有的鍵

>>> def dest(*arge,**kwarges):
	print("arge:",arge)
	print("kwarges:",kwarges)
#定義兩個資料用於使用
>>> a = (1,2,3,4,5)
>>> b = {'name':'小明','age':'18','sex':'男'}

#不拆包,兩個引數都被當做成一個元素傳入到了*不定長變數中,**只接受鍵值對
>>> dest(a,b)
arge: ((1, 2, 3, 4, 5), {'name': '小明', 'age': '18', 'sex': '男'})
kwarges: {}

#進行拆包,兩個資料被拆包成多個數據傳入,字典被*拆包只會得到鍵值的元素,**不定長還是沒有得到資料
>>> dest(*a,*b)
arge: (1, 2, 3, 4, 5, 'name', 'age', 'sex')
kwarges: {}

#對字典資料使用**拆包,得到了鍵值對傳入,**不定長接收到了資料並打包成一個字典
>>> dest(*a,**b)
arge: (1, 2, 3, 4, 5)
kwarges: {'name': '小明', 'age': '18', 'sex': '男'}