1. 程式人生 > >Python記錄6:函式2,函式引數

Python記錄6:函式2,函式引數

# 一. 函式引數分為兩大類
# 形參:在函式定義階段括號定義的引數(變數名),稱之為形式引數
        #因為函式定義階段只是用一個符號表示表示一個引數,並沒有具體的值,所以稱之為形式引數,形參
# 實參:在函式呼叫階段括號內傳入值(變數值),稱之為實際引數
        #在函式呼叫階段,給了具體的數值,而不再是一個符號化的形式,所以這個叫做實際引數實參
# 形參與實參的關係:
# 在呼叫函式時實參的值會繫結給形參,這種繫結關係在函式呼叫結束立即解除

# def func(x,y,z):####這裡的xyz都是形參
#     # x=1
#     # y=2
#     # z=3
#     print(x)
#
# func(1,2,3)####這裡的123都是實參

# 二: 形參與實參的細分
# 1. 位置引數:
#    位置形參:指的是在函式定義階段按照從左到右的位置順序依次定義的形參
#    特點: 必須被傳值,多一個不行,少一個也不行

# def func(x,y,z):
#     print(x)
#     print(y)
#     print(z)

# func(1,2,3,4)####錯誤的呼叫,多給了一個位置實參
# func(1,2,)#####錯誤呼叫,少給了一個位置實參
# func(1,2,3)#####正確呼叫,這個引數不能多也不能少,具體的個數根據函式定義的時候的語法來
# 位置實參: 指的是在函式呼叫階段按照從左到右的順序依次傳入的值
# 特點: 與形參一一對應
# func(1,2,3)
# func(2,3,1)

# 2.關鍵字引數(單指關鍵字實參): 在函式呼叫階段,按照key=value形式為指定的形參賦值
# 特點: 可以完全打亂傳值的順序,但仍然能指名道姓地為指定的形參賦值
# 注意:可以混用位置實參與關鍵字實參,但是
#      1. 不能為同一個形參重複賦值
#      2. 位置實參必須放在關鍵字實參的前面
# def func(x,y,z):
#     print(x)
#     print(y)
#     print(z)
# func(1,2,3)
# func(z=3,x=1,y=2)
# func(1,x=3333,y=2,z=3)
# func(1,y=2,z=3)
# func(x=1,2,z=3)

# 3.預設引數(預設形參): 在函式定義階段,就已經為形參賦值
#        特點: 在定義階段就已經有值,意味著在呼叫階段可以不用傳值
#        注意: 可以混用位置形參與預設形參,但是
#            1. 位置形參必須放在預設形參前面
#            2. 預設形參的值只在函式定義階段賦值一次,定義之後的任何改動都無法影響預設形參的值
#            3. 預設形參的值通常應該是不可變型別
# def func(x,z=1111,y):
#     print(x)
#     print(y)
#     print(z)

# m=1000
# def func(x,y,z=m):
#     print(x)
#     print(y)
#     print(z)
#
# m=2000
# func(1,2)

# def func(x,y,hobbies=None):
#     if hobbies is None:
#         hobbies=[]
#     hobbies.append(y)
#     print('%s 的愛好列表 %s' %(x,hobbies))
#
# func('egon','read',)
# func('alex','piao',)
# func('wxx','eat',)


# def func(x,y,z=1111):
#     print(x)
#     print(y)
#     print(z)
#
# func(1,2,z=33333)

# def register(name,age,sex='male'):
#     print(name)
#     print(age)
#     print(sex)
#
# register('大保健',18,)
# register('小保健',28,)
# register('中保健',38,)
# register('kevin',38,'female')

#4. 可變長引數: 指的是在呼叫函式時傳入的值(實參)個數不固定,而實參無非兩種,一種位置實參
# 另外一種就是關鍵字實參,針對這兩種形式實參的個數不固定,對應著形參也應該有兩種解決方案
# 來分別應對溢位位置實參(*)與關鍵字實參(**)

#*的用法
#一個* 如果用在定義函式階段,用在形參裡面,會把後面傳遞過來的多了的引數,自動存成元組的形式
#      如果用在函式的呼叫階段,用在實參裡面,會把後面需要傳遞的實參,列表,元組,字典等自動打散傳遞給前面的形參
#I: 在形參中出現*: *會將溢位的位置實參存成元組的形式,然後賦值緊跟其後的形參z
# def func(x,y,*z): #z=(3,4,5)
#     print(x)
#     print(y)
#     print(z)
#
# func(1,2,3,4,5)

#II: 在實參中出現*: 但凡是在實參中出現*,都將*後的值打散成位置實參,然後再進行賦值
def func(x,y,z):
    print(x)
    print(y)
    print(z)

#func(1,2,*[3,4,5,6,7]) #func(1,2,3,4,5,6,7)這種呼叫會報錯,因為打散之後會有七個實參傳遞給前面的三個形參,多了四個
# func(*[3,4,5]) #func(3,4,5)#####這個呼叫剛剛好,因為一個列表打散之後變成三個實參剛好傳遞給前面的是哪個形參
#func(*{'a':1,'b':2,'c':3}) #func('a','b','c')###字典打散之後只會講key傳遞給前面的實參

#**的用法
#這個是針對關鍵字引數
#I: 在形參中出現**: **會將溢位的關鍵實參存成字典的形式,然後賦值緊跟其後的形參z
# def func(x,y,**z): #z={'m':3,'a':1,'b':2}
#     print(x)
#     print(y)
#     print(z)
#
# func(1,y=2,m=3,a=1,b=2)

#II: 在實參中出現**: 但凡是在實參中出現**,都將**後的值打算成關鍵字實參,然後再進行賦值
#一般是字典才能打散成關鍵字引數
# def func(x,y,z):
#     print(x)
#     print(y)
#     print(z)

# func(1,2,**{'a':1,'b':2,'c':3}) #func(1,2,a=1,c=3,b=2)
# func(**{'y':1,'z':2,'x':3}) #func(z=2,x=3,y=1)



# 傳給外層函式wrapper的引數格式如何原封不動地轉嫁給wrapper內部呼叫的函式index???,解決方案如下
# def index(a,b,c):
#     print('from index',a,b,c)
#
# def wrapper(*args,**kwargs): #args=(1,2,3)   kwargs={'x':1,'y':2,'z':3}
#前面的args 表示位置形參,後面傳來的位置實參,不管多少,都會以元組的形式存放在這裡面
#kwargs表示關鍵字形參嗎,後面傳來的關鍵字實參,不管多少個,都會以字典的形式存放在這裡面
#特別的,args 和kwargs都只是一個代指的符號,沒有特別的含義,只是我們習慣上用著兩個字串表示而已,
#用其他的字串也可以,但是一般習慣用這個。稍微記一下就行
#index(*args,**kwargs)
# #index(*(1,2,3),**{'x':1,'y':2,'z':3})
# #index(1,2,3,x=1,y=2,z=3)
# # wrapper(1,2,3,x=1,y=2,z=3)
# wrapper(1,c=3,b=2)


# 5. 命名關鍵字形參: 在定義函式階段,但凡是在*與**之間的引數稱之為命名關鍵字形參
#    特點: 必須被傳值, 並且在傳值時必須按照key=value的形式傳值

# def func(x,*,m=111,n,**kwargs):
#     print(x)
#     print(m)
#     print(n)
#     print(kwargs)
#
# # func(1,n=3,m=2)
# func(1,n=3)

# def func(x,y=2,*args,m,**kwargs):
#     print(x)
#     print(y)
#     print(args)
#     print(m)
#     print(kwargs)
# func(1,200,3,4,5,m=111)