1. 程式人生 > 其它 >9、函式的引數

9、函式的引數

位置引數

def func(name, age, gender):
    print(name, age, gender)

  name,age和gender都是函式func的位置引數,位置引數必須被傳值,否則會報錯

關鍵字引數

  關鍵字引數指實參,實參以key=value的形式向形參傳值

def func(name, age, gender):
    print(name, age, gender)


# 關鍵字引數說的是實參傳值給形參的方式
func(name='zh', age=18, gender='')

預設引數

def func(name, gender, age=18):
    
print(name, age, gender)

  需要注意:預設引數必須在位置引數之後

       預設引數的值在函式定義階段被賦值一次

x = 1


def foo(arg=x):
    print(arg)


x = 5
foo()  # 1

  預設引數的值應該是不可變型別,如果設定成可變型別,可能會出現下面這種問題

  按照理解,每一次的L都應該只有111,但是,隨著函式一直被呼叫,L中的元素不斷變多,因為L在初始化時指向一個不可變物件,這個物件的值被改變,但是不會改變它的記憶體地址,導致L的記憶體地址一致沒有改變,所以元素會越來越多

def foo(L=[]):
    L.append(
'111') print(L) foo() # ['111'] foo() # ['111', '111'] foo() # ['111', '111', '111'] foo() # ['111', '111', '111', '111']

  如果預設值是不可變型別,就不會有這個問題

def foo(n, arg=None):
    if arg is None:
        arg = []
    arg.append(n)
    return arg


print(foo(1))   # [1]

print(foo(2))   # [2]
print(foo(3)) # [3]

可變長度的預設引數

  如果在最後一個形參名前加上一個*,那麼在呼叫函式時,溢位的位置實參,都會被接收,以元組的形式儲存下來賦值給這個形參

def foo(x, y, z=1, *args):
    print(x)
    print(y)
    print(z)
    print(args)


foo(1, 2, 3, 4, 5, 6)       
# 1
# 2
# 3
# (4, 5, 6)

  如果事先產生了一個列表,也可以傳入函式

def foo(x, y, z=1, *args):
    print(x)
    print(y)
    print(z)
    print(args)


L = [223, 434, 666]
foo(1, 2, 3, *L)
# 1
# 2
# 3
# (223, 434, 666)

  PS:*在實參的時候作用是打散,在形參的作用是聚合

可變長度的關鍵字引數

  如果在最後一個形參名前加**號,那麼在呼叫函式時,溢位的關鍵字引數都會被接收

def foo(x, **kwargs):
    print(x)
    print(kwargs)


foo(1, y=2, z=3)
# 1
# {'y': 2, 'z': 3}

  同樣可以用**來打散一個字典

def foo(x, **kwargs):
    print(x)
    print(kwargs)


dic = {'a': 1, 'b': 2}
foo(1, **dic)
# 1
# {'a': 1, 'b': 2}

命名關鍵字引數

  如果想要限定呼叫者必須以key=value的形式傳遞引數Python3提供了專門的語法:需要在定義形參時,用作為一個分隔符號,號之後的形參稱為命名關鍵字引數。對於這類引數,在函式呼叫時,必須按照key=value的形式為其傳值,且必須被傳值

def foo(name, age, *, height, sex):
    pass


foo('lili', 18, height=1.7, sex='male')

  命名關鍵字引數也可以有預設值

  如果形參中已經有了可變長度的關鍵字引數,那麼命名關鍵字引數不需要加上*分隔符

def foo(name, age, *args, height, sex):
    pass

組合使用

  所有引數可任意組合使用,但定義順序必須是:位置引數、預設引數、args、命名關鍵字引數、*kwargs

  可變引數*args與關鍵字引數kwargs通常是組合在一起使用的,如果一個函式的形參為*args與kwargs,那麼代表該函式可以接收任何形式、任意長度的引數

def foo(*args, **kwargs):
    pass