1. 程式人生 > 實用技巧 >python的函式引數

python的函式引數

python 的定義函式有多種引數(必選引數(也稱位置引數)、預設引數、可變引數、關鍵字引數、命名關鍵字引數)

全文參考廖雪峰老師的網站https://www.liaoxuefeng.com/wiki/1016959663602400/1017261630425888

1.必須引數:這個就是最常見,最基礎的函式定義引數

#x和n都是必選引數
def new_power(x,n):
    s=1
    while n>0:
        n=n-1
        s=s*x
    return(s)

2.預設引數:當函式的引數變化不大時,可以使用預設值代替(注意定義預設引數要牢記一點:預設引數必須指向不變物件!

#n=2就是預設引數
def new_power(x,n=2):
    s=1
    while n>0:
        n=n-1
        s=s*x
    return(s)

#呼叫的時候可以不寫n=2
new_power(5)  #25

注意:必選引數在前,預設引數在後,否則Python的直譯器會報錯,當函式有多個引數時,把變化大的引數放前面,變化小的引數放後面。變化小的引數就可以作為預設引數

#當於預設引數不符合時,需要提供預設引數的值
def enroll(name, gender, age=6, city='Beijing'):
    print('
name:', name) print('gender:', gender) print('age:', age) print('city:', city) #必須傳入預設引數的新值
enroll('Tom','M',city='Tianjing')

enroll('Tom','M',7)
#要注意這種情況,定義預設引數要牢記一點:預設引數必須指向不變物件!
def add_end(L=[]):
    L.append('END')
    return L

#Python函式在定義的時候,預設引數L的值就被計算出來了,即[],因為預設引數L也是一個變數,它指向物件[],每次呼叫該函式,如果改變了L的內容,則下次呼叫時,預設引數的內容就變了,不再是函式定義時的[]了
add_end() #['END'] add_end() #['END', 'END'] add_end() #['END', 'END', 'END']

3.可變引數(*):當變數是可變時,可以使用*,這樣就可以傳入任意個引數,包括0個引數

#當變數是可變的,如變數是一個list或者tuple
def calc(numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum

#呼叫時,需要先組裝一個一個list或tuple
calc([1,2,3])
calc((1,2,3,4))

可變引數呼叫時就不需要定義一個list或者tuple

def calc(*numbers):
    sum=0
    for n in numbers:
        sum=sum+n*n
    return sum


#呼叫
calc(1,2,3,4)

如果已經有了一個list或者tuple:直接在list或者tuple前面加上一個*號

#方法一
num=[1,2,3]
calc(num[0],num[1],num[2])



#方法二
num=[1,2,3]
calc(*num)

4.關鍵字引數(**):關鍵字引數允許你傳入0個或任意個含引數名的引數,這些關鍵字引數在函式內部自動組裝為一個dict

關鍵字引數有什麼用?它可以擴充套件函式的功能,試想你正在做一個使用者註冊的功能,除了使用者名稱和年齡是必填項外,其他都是可選項,利用關鍵字引數來定義這個函式就能滿足註冊的需求

def person(name, age, **kw):
    print('name:', name, 'age:', age, 'other:', kw)


#呼叫,只傳入必選引數
person('Michael', 30)  #name: Michael age: 30 other: {}

#傳入任意個關鍵字引數
person('Bob', 35, city='Beijing')  #name: Bob age: 35 other: {'city': 'Beijing'}
person('Adam', 45, gender='M', job='Engineer')  #name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}

#和可變引數類似,也可以先組裝出一個dict,然後,把該dict轉換為關鍵字引數傳進去
extra = {'city': 'Beijing', 'job': 'Engineer'}
 person('Jack', 24, city=extra['city'], job=extra['job'])  #name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}

#上面的也可以這樣呼叫
person('Jack', 24, **extra)

5.命名關鍵字引數:對於關鍵字引數,函式的呼叫者可以傳入任意不受限制的關鍵字引數。至於到底傳入了哪些,就需要在函式內部通過kw檢查

#仍以person()函式為例,我們希望檢查是否有city和job引數:
def person(name, age, **kw):
    if 'city' in kw:
        # 有city引數
        pass
    if 'job' in kw:
        # 有job引數
        pass
    print('name:', name, 'age:', age, 'other:', kw)

#但是呼叫者仍可以傳入不受限制的關鍵字引數
person('Jack', 24, city='Beijing', addr='Chaoyang', zipcode=123456)  #name: Jack age: 24 other: {'city': 'Beijing', 'addr': 'Chaoyang', 'zipcode': 123456}

如果要限制關鍵字引數的名字,就可以用命名關鍵字引數,和關鍵字引數**kw不同,命名關鍵字引數需要一個特殊分隔符**後面的引數被視為命名關鍵字引數

#這種方式定義的函式如下:
def person(name, age, *, city, job):
    print(name, age, city, job)

#呼叫方式:
person('Jack', 24, city='Beijing', job='Engineer')

如果函式定義中已經有了一個可變引數,後面跟著的命名關鍵字引數就不再需要一個特殊分隔符*了:

def person(name, age, *args, city, job):
    print(name, age, args, city, job)

還有下面這些需要注意的

#1.命名關鍵字引數必須傳入引數名,如果沒有傳入引數名,呼叫將報錯:
 person('Jack', 24, 'Beijing', 'Engineer')
輸出:Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: person() takes 2 positional arguments but 4 were given


#2.命名關鍵字引數可以有預設值,從而簡化呼叫:
def person(name, age, *, city='Beijing', job):
    print(name, age, city, job)

#由於命名關鍵字引數city具有預設值,呼叫時,可不傳入city引數:
person('Jack', 24, job='Engineer')

#3.使用命名關鍵字引數時,要特別注意,如果沒有可變引數,就必須加一個*作為特殊分隔符。如果缺少*,Python直譯器將無法識別位置引數和命名關鍵字引數:
def person(name, age, city, job):
    # 缺少 *,city和job被視為位置引數
    pass

6.引數組合

在Python中定義函式,可以用必選引數、預設引數、可變引數、關鍵字引數和命名關鍵字引數,這5種引數都可以組合使用。但是請注意,引數定義的順序必須是:必選引數、預設引數、可變引數、命名關鍵字引數和關鍵字引數

#比如定義一個函式,包含上述若干種引數:
def f1(a, b, c=0, *args, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)

def f2(a, b, c=0, *, d, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)


f1(1, 2)  #a = 1 b = 2 c = 0 args = () kw = {}
f1(1, 2, c=3)  #a = 1 b = 2 c = 3 args = () kw = {}
f1(1, 2, 3, 'a', 'b')  #a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
f1(1, 2, 3, 'a', 'b', x=99)  #a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}
f2(1, 2, d=99, ext=None)  #a = 1 b = 2 c = 0 d = 99 kw = {'ext': None}

最神奇的是通過一個tuple和dict,你也可以呼叫上述函式:

#例子
args = (1, 2, 3, 4)
kw = {'d': 99, 'x': '#'}
f1(*args, **kw)  #a = 1 b = 2 c = 3 args = (4,) kw = {'d': 99, 'x': '#'}


args = (1, 2, 3)
kw = {'d': 88, 'x': '#'}
f2(*args, **kw)  #a = 1 b = 2 c = 3 d = 88 kw = {'x': '#'}