1. 程式人生 > >5、python基礎——函式引數

5、python基礎——函式引數

參考原文:http://www.cnblogs.com/superwuchaofan/p/7118169.html
python中函式的引數

形參:定義函式時代表函式的形式引數
定義函式時,形參分為普通引數預設引數,和動態引數(普通動態引數,關鍵字動態引數)
順序:普通引數,預設引數,※args,※※kwargs
實參:呼叫函式時傳入的實際引數
呼叫函式時,根據呼叫時的寫法,可以分為位置引數關鍵字引數

def f(x, y):  # 普通引數
    pass

def f(x, y=1):  # y=1是預設引數
    pass

def(x,y=1,*args):  # *args普通動態引數
    pass

def(x,y=1,**kwargs):  # **kwargs關鍵字動態引數
    pass
def f(x,y):
    print('x=',x,'y'=,y)

f(1,2)  #我們這樣呼叫的時候1,2叫位置引數,會根據傳入的實參
          #位置去對於形參的位置


輸出結果為:
 x= 1 y= 2 


f(x=1, y=2)
f(y=2, x=1)  #我們這樣呼叫的時候,y=2,x=1叫做關鍵字引數
                   #可以不用按照位置寫
#同時寫位置引數和關鍵字引數呢
f(x=1, 2)  # 當我們把關鍵字引數放前面  #報錯
#結論:關鍵字引數不能放在位置引數前面,這個是語法規定
f(1, x=2)   #調換位置,報錯
#結論:如果位置引數和關鍵字引數需要同時匹配
f(2,y=1)  #正確

普通動態引數:

def f(x, *args):
    print(args)
f(1, 2, '3', [1, 2, 3])
f(3, 2, [1, 2, 3])

執行結果:
(2, '3', [1, 2, 3])
(2, [1, 2, 3])

普通動態引數會將傳入的所有多餘的位置引數組合成一個元祖

關鍵字動態引數:

def f(x, y=1, **kwargs):
    print(kwargs)
f(1, 2, z=2, a=3, d=4)
f(3, 2, xx=2, name='xinlan', age=18)

執行結果:
{'a': 3, 'z': 2, 'd': 4}
{'age': 18, 'xx': 2, 'name': 'xinlan'}

結論:關鍵字動態引數會將傳入的多餘的關鍵字引數組合成一個字典

d = {
    'name': 'xinlan',
    'age': 18
}


def f(**kwargs):
    print(kwargs)

f(**d)
f(name='xinlan', age=18)

執行結果:
{'name': 'xinlan', 'age': 18}
{'name': 'xinlan', 'age': 18}

結論:將一個字典前加上※※傳入一個函式,相當於將這個字典中的鍵值對以關鍵字引數的形式傳入函式。

l = ['python', 'php', 'java']


def f(*args):
    print(args)

f(*l)
f('python', 'php', 'java')

結論:將一個列表前加上*傳入一個函式,相當於將這個列表中的元素按順序傳入函式

預設引數:預設引數的作用就是,如果我們在呼叫函式的時候不傳入相應的引數,那麼函式就用預設值

def f(y=[]):
    y.append('ok')
    print(y)
f()
f()
f()
執行結果:
['ok']
['ok', 'ok']
['ok', 'ok', 'ok']

解釋:呼叫了兩次f函式,發現輸出的結果不一樣。這是因為列表,字典等這樣的資料型別在呼叫的時候是引用它們的地址。

直譯器在執行y=[]的時候,y指向的一個列表的引用地址,這個列表發生變化後,y指向的地址是沒有變的

所以我們在定義函式的時候,預設引數不要定義成列表,字典等資料型別。
解決辦法:

def f(y=None):  # 這裡None是一個佔位符 
    if not y:
        y = []
    y.append('ok')
    print(y)

f()
f()
執行結果:
['ok']
['ok']