『無為則無心』Python函數 — 26、Python函數參數的傳遞方式


提示:上一篇文章介紹了Python中函數的基本使用,本篇文章主要說明一下Python函數實參的傳遞方式

1、位置參數

位置參數:調用函數時根據函數定義的參數位置來傳遞參數。

def user_info(name, age, gender):
    print(f'您的名字是{name}, 年齡是{age}, 性別是{gender}')

# 調用函數
user_info('TOM', 20, '男')

注意:傳遞和定義參數的順序及個數必須一致。就是將對應位置的實參復制給對應位置的形參,第一個實參賦值給第一個形參,第二個實參賦值給第二個形參,以此類推。

示例

def user_info(name, age, gender):
    print(f'您的名字是{name}, 年齡是{age}, 性別是{gender}')

# 1.調用函數,傳遞的參數個數不正確
# 結果:TypeError: user_info() missing 1 required positional argument: 'gender'
user_info('TOM', 20)

# 2.調用函數,傳遞的參數的順序不正確
# 不會報錯,但輸出的內容完全歧義。
# 結果:您的名字是男, 年齡是TOM, 性別是20
user_info('男', 'TOM', 20)

2、關鍵字參數

可以不按照形參定義的順序去傳遞,而直接根據參數名去傳遞參數。

函數調用,通過鍵=值形式加以指定。

可以讓函數更加清晰、容易使用,同時也清除了參數的需求。

def user_info(name, age, gender):
    print(f'您的名字是{name}, 年齡是{age}, 性別是{gender}')

# 正確用法
user_info('Rose', age=20, gender='女')
user_info('小明', gender='男', age=16)

# 位置參數必須寫在關鍵字參數的前面
# 結果:SyntaxError: positional argument follows keyword argument
user_info(gender='男', age=16, "孫悟空")

# 位置參數必須寫在關鍵字參數的前面,同時位置參數的順序也要對應
# 結果:TypeError: user_info() got multiple values for argument 'age'
user_info("孫悟空", '男', age=16)

# 格式正確,但是位置參數的順序不正確,結果也會產生歧義。
# 結果:您的名字是20, 年齡是孫悟空, 性別是男
user_info(20, "孫悟空", gender='男')

"""
總結:定義參數時,位置參數和關鍵字參數,盡量統一使用一種。
"""

注意:

  • 位置參數和關鍵字參數可以混合使用。
  • 函數調用時,如果有位置參數時,位置參數必須在關鍵字參數的前面,但關鍵字參數之間不存在先后順序。

3、缺省參數(默認參數)

缺省參數也叫默認參數,用於定義函數時,為參數提供默認值,調用函數時可不傳該默認參數的值。

提示:所有位置參數必須出現在默認參數前(因為默認參數的格式和關鍵字參數格式一樣,所以都要寫在所有參數之后),包括函數定義和調用。

def user_info(name, age, gender='男'):
    print(f'您的名字是{name}, 年齡是{age}, 性別是{gender}')

# 沒有為缺省參數傳值,表示使用默認值。
user_info('TOM', 20)
# 為缺省參數傳值,使用這個值,即修改了默認值。
user_info('Rose', 18, '女')

注意:函數調用時,如果為缺省參數傳值則修改默認參數值,否則使用這個默認值。

4、不定長參數(可變參數)

不定長參數也叫可變參數。用於不確定調用的時候會傳遞多少個參數(不傳參也可以)的場景。此時,可用包裹位置參數,或者包裹關鍵字參數,來進行參數傳遞,會顯得非常方便。

(1)包裹位置傳遞

"""
1.在定義函數時,可以在形參前邊加上一個*,這樣這個形參將會獲取到所有的實參,
它將會將所有的實參保存到一個元組中
2.*args說明:*一定要寫,args表示形參,可以自定義名稱。
但在實際工作中,一般默認使用*args做為不定長包裹位置傳遞參數的表示,不做修改。
"""
def user_info(*args):
    print(args)


# ('TOM',)
user_info('TOM')
# ('TOM', 18)
user_info('TOM', 18)
# ()
user_info()

注意:傳進的所有參數都會被args變量收集,它會根據傳進的所有的位置實參,合並為一個元組(tuple),args是元組類型,這就是包裹位置傳遞。(這個過程也叫裝包或者組包)

小應用

# 定義一個函數,可以求任意個數字的和
def sum(*nums):
    # 定義一個變量,來保存結果
    result = 0
    # 遍歷元組,並將元組中的數進行累加
    for n in nums:
        result += n
    print(result)


sum(123, 456, 789, 10, 20, 30, 40)

注意事項

# 注意事項1
# 帶星號的形參只能有一個
# 帶星號的參數,可以和其他參數配合使用
# 第一個參數給a,第二個參數給b,剩下的都保存到c的元組中
def fn2(a, b, *c):
    print('a =', a)
    print('b =', b)
    print('c =', c)

fn2(1, 2, 3, 4, 5)
"""
輸出結果:
a = 1
b = 2
c = (3, 4, 5)
"""

# 注意事項2
# 可變參數不是必須寫在最后,但是注意,
# 帶*的參數后的所有參數,必須以關鍵字參數的形式傳遞
# 第一個參數給a,剩下的位置參數給b的元組,c必須使用關鍵字參數
def fn2(a, *b, c):
    print('a =', a)
    print('b =', b)
    print('c =', c)
# TypeError: fn2() missing 1 required keyword-only argument: 'c'
# fn2(1, 2, 3, 4, 5) # 報錯
fn2(1, 2, 3, 4, c=5)
"""
輸出結果:
a = 1
b = (2, 3, 4)
c = 5
"""

# 注意事項3
# 所有的位置參數都給a,b和c必須使用關鍵字參數,
# 且必須寫在最后。
def fn2(*a, b, c):
    print('a =', a)
    print('b =', b)
    print('c =', c)

fn2(1, 2, 3, b=4, c=5)
"""
輸出結果:
a = (1, 2, 3)
b = 4
c = 5
"""

# 注意事項4
# 如果在形參的開頭直接寫一個*,
# 則要求我們的所有的參數必須以關鍵字參數的形式傳遞。
def fn2(*, a, b, c):
    print('a =', a)
    print('b =', b)
    print('c =', c)

fn2(a=3, b=4, c=5)
"""
輸出結果:
a = 3
b = 4
c = 5
"""

# 注意事項5
# *形參只能接收位置參數,而不能接收關鍵字參數
def fn3(*a):
    print('a =', a)
# TypeError: fn3() got an unexpected keyword argument 'a'
fn3(a=3, b=4, c=5)

(2)包裹關鍵字傳遞

"""
**kwargs說明:**一定要寫,args表示形參,可以自定義名稱。
但在實際工作中,一般默認使用**kwargs做為不定長包裹關鍵字傳遞參數的表示,不做修改。
"""
# 收集所有關鍵字參數,它會將這些參數統一保存到一個字典中返回。
# 字典的key就是參數的名字,字典的value就是參數的值
def user_info(**kwargs):
    print(kwargs)

# {'name': 'TOM', 'age': 18, 'id': 110}
# 關鍵字不能加引號,應為關鍵字對應的是形參。
user_info(name='TOM', age=18, id=110)


# 包裹關鍵字傳遞只能有一個,並且必須寫在所有參數的最后
# 實參可以不按順序傳遞
def fn3(b, c, **a):
    print('a =', a, type(a))
    print('b =', b)
    print('c =', c)

fn3(e=10, b=1, d=2, c=3, f=20)
"""
輸出結果:
a = {'e': 10, 'd': 2, 'f': 20} <class 'dict'>
b = 1
c = 3
"""

綜上:無論是包裹位置傳遞還是包裹關鍵字傳遞,都是一個組包的過程(組包簡單的說,就是收集分散的參數,返回一個整體數據)。關於組包對應就是拆包,在之前的文章【Python元組】中有介紹,可以對應的查看。

5、位置參數、默認參數、可變參數的混合使用

參數定義與調用順序的基本原則是:位置參數,默認參數,包裹位置,包裹關鍵字。(定義和調用都應遵循)

提示:默認參數與包裹位置參數可以根據需求進行位置調換。

def user_info(name, age, sex=1, *args, **kargs):
    print(name, age, sex, args, kargs)


user_info('TOM', 18, 2, 'music', 'sport', id=101)

# 輸出結果
# TOM 18 2 ('music', 'sport') {'id': 101}

6、拓展:參數解包

關於組包對應就是拆包,在之前的文章【Python元組】中有介紹,可以對應的查看。

(1)通過包裹位置對一個元組進行解包

操作方式:使用*號。

如下示例:

# 參數的解包(拆包)
def fn4(a, b, c):
    print('a =', a)
    print('b =', b)
    print('c =', c)


# 創建一個元組
t = (10, 20, 30)

# 我們直接傳遞t,會報錯
# TypeError: fn4() missing 2 required positional arguments: 'b' and 'c'
# fn4(t)

# 而以前我們是這樣拆包的
# fn4(t[0], t[1], t[2])
"""
輸出結果:
a = 10
b = 20
c = 30
"""

# *號拆包
# 傳遞實參時,也可以在序列類型的參數前添加星號,
# #這樣他會自動將序列中的元素依次作為參數傳遞。
# 這里要求序列中元素的個數必須和形參的個數的一致
fn4(*t)
"""
輸出結果:
a = 10
b = 20
c = 30
"""

(2)通過包裹關鍵字對一個字典進行解包

操作方式:使用**號。

如下示例:

# 參數的解包(拆包)
def fn4(a, b, c):
    print('a =', a)
    print('b =', b)
    print('c =', c)


# 創建一個字典
d = {'a': 100, 'b': 200, 'c': 300}
# 通過 **來對一個字典進行解包操作
# 字典中的key要和函數的形參一一對應。
fn4(**d)
"""
輸出結果:
a = 100
b = 200
c = 300
"""


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM