函式定義支持可變數量的引數,下面列出三種可以組合使用的形式,
1 默認值引數
為引數指定默認值,在呼叫函式時可以使用比定義時更少的引數,
def student_info(name, sex, age=18, score=100):
if sex == 'male':
print(f"{name} is {age} years old, his score is {score}")
else:
print(f"{name} is {age} years old, her score is {score}")
該函式接收兩個必選引數name 和 sex ,兩個可選引數 age ,score ,該函式可用下列方式呼叫
- 只傳入必選引數
student_info('ZhangSan', 'male')
# zhangSan is 18 years old, his score is 100.
- 傳入一個可選引數
student_info('LiSi', 'female', 17)
# LiSi is 17 years old, her score is 100.
- 傳入所有實參
student_info('XiaoHong', 'female', 17, 99)
# XiaoHong is 17 years old, her score is 99.
2 關鍵字引數
kwarg=value 形式的 關鍵字引數 也可以用于呼叫函式,
def student_info(name, sex, age=18, score=100):
if sex == 'male':
print(f"{name} is {age} years old, his score is {score}")
else:
print(f"{name} is {age} years old, her score is {score}")
使用了默認值引數的函式都可以通過kwarg=value 形式的關鍵字引數呼叫函式,該函式可以通過下列方式呼叫,
student_info('ZhangSan', 'male')
student_info('ZhangSan', 'male', age=17)
student_info('ZhangSan', 'male', score=99)
student_info('ZhangSan', 'male', age=19, score=98)
student_info('ZhangSan', 'male', score=95, age=20)
從上面呼叫函式的方式可以看出:
- 關鍵字引數的順序可以和定義的順序不一致
- 關鍵字引數必須放在位置引數之后
如果你想打亂所有引數的順序,包括位置引數,那么你需要對所有引數使用kwarg=value 的方式來傳入實參,如:
student_info(score=100, age=19, name='ZhangSan', sex='malae')
不能在一次呼叫中多次對同一個引數進行賦值(即使多次賦值都是同一個值):
student_info('ZhangSan', 'male', name='ZhangSan')
這樣是不被允許的,
**name
當最后一個形參為**name 形式時,接收一個字典,該字典包含與函式中已定義形參之外的所有關鍵字引數,**name可以和*name形參組合使用(注意:*name必須在**name前面),*name接收一個元組,該元組包含形參串列之外的位置引數,
其中**name接收的字典中資料的順序和呼叫函式時實參傳入的順序一致,
3 特殊引數
默認情況下,引數可以按位置或顯式關鍵字傳遞給 Python 函式,為了讓代碼易讀、高效,最好限制引數的傳遞方式,這樣,開發者只需查看函式定義,即可確定引數項是僅按位置、按位置或關鍵字,還是僅按關鍵字傳遞,需要使用/和*,
函式定義如下:
def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
----------- ----------- ----------
| | |
| | |
位置引數 位置引數或關鍵字引數 關鍵字引數
其中/ 和* 是可選的,
3.1 位置或關鍵字引數
當函式定義中未使用/和*時,引數可以按照位置或關鍵字傳遞給函式,
3.2 僅位置引數
特定形參可以標記為 僅限位置,僅限位置 時,形參的順序很重要,且這些形參不能用關鍵字傳遞,僅限位置形參應放在 / (正斜杠)前,/ 用于在邏輯上分割僅限位置形參與其它形參,如果函式定義中沒有 /,則表示沒有僅限位置形參,
/ 后可以是 位置或關鍵字 或 僅限關鍵字 形參,
3.3 僅限關鍵字引數
把形參標記為僅限關鍵字,表明必須以關鍵字引數的形式傳遞該引數,
3.4 函式示例
def standard_arg(arg):
print(arg)
def pos_only_arg(arg, /):
print(arg)
def kwd_only_arg(*, arg):
print(arg)
def combined_example(pos_only, /, standard, *, kwd_only):
print(pos_only, standard, kwd_only)
第一個函式 standard_arg 的函式定義對呼叫的方式沒有任何限制,可以按位置也可以按關鍵字傳遞引數:
standard_aeg(2)
standard_aeg(arg=2)
第二個函式 pos_only_arg 的函式定義中有 / ,且形參全在 / 之前定義,所以僅限使用位置引數,
pos_only_arg(3)
pos_only_arg(arg=3) # 無效的呼叫
# TypeError: pos_only_arg() got some positional-only arguments passed as keyword arguments: 'arg'
第三個函式 kwd_only_arg 的函式定義通過 * 表明僅限關鍵字引數,
kwd_only_arg(arg=5)
kwd_only_arg(5) # 無效的呼叫
# TypeError: kwd_only_arg() takes 0 positional arguments but 1 was given
最后一個函式 combined_example 的函式定義中,使用了全部三種呼叫慣例:
- 該函式接收三個引數
- 第一個引數僅限位置引數
- 第二個引數可使用位置或關鍵字引數
- 第三個引數僅限關鍵字引數
combined_example(6, 7, kwd_only=8)
combined_example(6, standard=7, kwd_only=8)
下面的函式定義中,kwds 里面不能把 name 當做鍵,會與第一個引數 name 沖突,
def foo(name, **kwds):
print(name, **kwds)
foo(1, **{name: 2})
因為上面的函式呼叫相當于把name 賦值了兩次,等價于:
foo(1, name=2)
由于此時name 既可以當作位置引數,也可以當作關鍵字引數,所以上述行為相當于給一個引數在一次函式呼叫中賦值了兩次,
那么如何才能讓 kwds 使用 name 當作鍵呢?
這就需要使用 特殊引數 / 來解決了,只要把 name 引數僅限使用位置引數,那么再使用name=2 時就不會被認為是第二次賦值了,
所以需要把函式定義為:
def foo(name, /, **kwds):
print(name, kwds)
foo(1, name=2, age=18)
# 1 {'name': 2, 'age': 18}
就可以了,??
總結:僅限位置形參的名稱可以在**kwds中使用,而不產生歧義,
4 任意實參串列
呼叫函式時,使用任意數量的實參是最少見的選項,這些實參包含在元組中,
有時候,需要接受任意數量的實參,但預先不知道傳遞給函式的會是什么樣的資訊,在這種 情況下,可將函式撰寫成能夠接受任意數量的鍵值對——呼叫陳述句提供了多少就接受多少,
def sumnum(a, *ddd):
print(a)
result = a
for num in ddd:
result += num
return result
print(sumnum(1, 2, 3, 5, 6, 9, 8, 7))
# 1
# 41
*name 用于接收傳遞給函式的所有剩余位置引數,因此*name 的后面不允許出現位置引數,而是僅限關鍵字引數,同樣的*name 的前面也不允許出現任何的關鍵字引數,而是僅限位置引數,
5 解包實參串列
函式呼叫要求獨立的位置引數,但實參在串列或元組里時,要執行相反的操作,例如,內置的 range() 函式要求獨立的 start 和 stop 實參,如果這些引數不是獨立的,則要在呼叫函式時,用 * 運算子把實參從串列或元組解包出來:
>>> list(range(3, 6))
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(*args))
[3, 4, 5]
同樣,字典可以用 ** 運算子傳遞關鍵字引數,
6 Lambda 運算式
Lambda 關鍵字用于創建小巧的匿名函式,
Lambda a, b: a+b
上面的函式回傳兩個引數的和,Lambda 函式可用于任何需要函式物件的地方,在語法上,匿名函式只能是單個運算式,在語意上,它只是常規函式定義的語法糖,與嵌套函式定義一樣,lambda 函式可以參考包含作用域中的變數:
def make_incrementor(n):
return lambda x: x + n
f = make_incrementor(42)
print(f(0))
# 42
print(f(1))
# 43
上例用 lambda 運算式回傳函式,還可以把匿名函式用作傳遞的實參:
pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
pairs.sort(key=lambda pa: pa[1])
print(pairs)
# [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/298840.html
標籤:其他
上一篇:Python所有的學習路線,你要的知識體系在這,千萬別做了無用功
下一篇:MySQL索引詳細
