Python學習筆記 函式引數

2021-08-28 11:04:27 字數 4413 閱讀 3066

power(x, n)函式有兩個引數:x和n,這兩個引數都是位置引數,呼叫函式時,傳入的兩個值按照位置順序依次賦給引數x和n

def power(x, n=2):

s = 1

while n > 0:

n = n - 1

s = s * x

return s

預設引數必須指向不變物件!

設定預設引數時,有幾點要注意:

一是必選引數在前,預設引數在後,否則python的直譯器會報錯;

二是如何設定預設引數。

有多個預設引數時,呼叫的時候,既可以按順序提供預設引數,比如呼叫enroll(『bob』, 『m』, 7),意思是,除了name,gender這兩個引數外,最後1個引數應用在引數age上,city引數由於沒有提供,仍然使用預設值。

也可以不按順序提供部分預設引數。當不按順序提供部分預設引數時,需要把引數名寫上。比如呼叫enroll(『adam』, 『m』, city=『tianjin』),意思是,city引數用傳進去的值,其他預設引數繼續使用預設值。

可變引數就是傳入的引數個數是可變的,可以是1個、2個到任意個,還可以是0個。

def calc(*numbers):

sum = 0

for n in numbers:

sum = sum + n * n

return sum

定義可變引數和定義乙個list或tuple引數相比,僅僅在引數前面加了乙個*號。在函式內部,引數numbers接收到的是乙個tuple。

python允許你在list或tuple前面加乙個*號,把list或tuple的元素變成可變引數傳進去:

>>> nums = [1, 2, 3]

>>> calc(*nums)

14

*nums表示把nums這個list的所有元素作為可變引數傳進去。這種寫法相當有用,而且很常見。

可變引數允許你傳入0個或任意個引數,這些可變引數在函式呼叫時自動組裝為乙個tuple。而關鍵字引數允許你傳入0個或任意個含引數名的引數,這些關鍵字引數在函式內部自動組裝為乙個dict。

def person(name, age, **kw):

print('name:', name, 'age:', age, 'other:', kw)

函式person除了必選引數name和age外,還接受關鍵字引數kw。在呼叫該函式時,可以只傳入必選引數:

>>> person('michael', 30)

name: michael age: 30 other: {}

>>> extra =

>>> person('jack', 24, **extra)

name: jack age: 24 other:

**extra表示把extra這個dict的所有key-value用關鍵字引數傳入到函式的**kw引數,kw將獲得乙個dict,注意kw獲得的dict是extra的乙份拷貝,對kw的改動不會影響到函式外的extra。

如果要限制關鍵字引數的名字,就可以用命名關鍵字引數,例如,只接收city和job作為關鍵字引數。這種方式定義的函式如下:

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

print(name, age, city, job)

和關鍵字引數**kw不同,命名關鍵字引數需要乙個特殊分隔符**後面的引數被視為命名關鍵字引數。

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

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

print(name, age, args, city, job)

命名關鍵字引數必須傳入引數名,這和位置引數不同。

命名關鍵字引數可以有預設值,從而簡化呼叫:

def person(name, age, *, city='beijing', job):

print(name, age, city, job)

由於命名關鍵字引數city具有預設值,呼叫時,可不傳入city引數:

>>> person('jack', 24, job='engineer')

jack 24 beijing engineer

使用命名關鍵字引數時,要特別注意,如果沒有可變引數,就必須加乙個*作為特殊分隔符。如果缺少*,python直譯器將無法識別位置引數和命名關鍵字引數:

def person(name, age, city, job):

# 缺少 *,city和job被視為位置引數

pass

在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)

在函式呼叫的時候,python直譯器自動按照引數位置和引數名把對應的引數傳進去。

>>> 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 =

>>> f2(1, 2, d=99, ext=none)

a = 1 b = 2 c = 0 d = 99 kw =

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

>>> args = (1, 2, 3, 4)

>>> kw =

>>> f1(*args, **kw)

a = 1 b = 2 c = 3 args = (4,) kw =

>>> args = (1, 2, 3)

>>> kw =

>>> f2(*args, **kw)

a = 1 b = 2 c = 3 d = 88 kw =

所以,對於任意函式,都可以通過類似func(*args, **kw)的形式呼叫它,無論它的引數是如何定義的。

python的函式具有非常靈活的引數形態,既可以實現簡單的呼叫,又可以傳入非常複雜的引數。

預設引數一定要用不可變物件,如果是可變物件,程式執行時會有邏輯錯誤!

要注意定義可變引數和關鍵字引數的語法:

*args是可變引數,args接收的是乙個tuple;

**kw是關鍵字引數,kw接收的是乙個dict。

以及呼叫函式時如何傳入可變引數和關鍵字引數的語法:

可變引數既可以直接傳入:func(1, 2, 3),又可以先組裝list或tuple,再通過*args傳入:func(*(1, 2, 3))

關鍵字引數既可以直接傳入:func(a=1, b=2),又可以先組裝dict,再通過**kw傳入:func(**)

使用*args**kw是python的習慣寫法,當然也可以用其他引數名,但最好使用習慣用法。

命名的關鍵字引數是為了限制呼叫者可以傳入的引數名,同時可以提供預設值。

定義命名的關鍵字引數在沒有可變引數的情況下不要忘了寫分隔符*,否則定義的將是位置引數。

使用遞迴函式的優點是邏輯簡單清晰,缺點是過深的呼叫會導致棧溢位。

針對尾遞迴優化的語言可以通過尾遞迴防止棧溢位。尾遞迴事實上和迴圈是等價的,沒有迴圈語句的程式語言只能通過尾遞迴實現迴圈。

python標準的直譯器沒有針對尾遞迴做優化,任何遞迴函式都存在棧溢位的問題。

Python學習筆記 函式引數

定義函式的時候,我們把引數的名字和位置確定下來,函式的介面定義就完成了。對於函式的呼叫者來說,只需要知道如何傳遞正確的引數,以及函式將返回什麼樣的值就夠了,函式內部的複雜邏輯被封裝起來,呼叫者無需了解。python的函式引數十分靈活,可以分為 必選引數 作為函式呼叫的介面所必須具備的引數。預設引數 ...

Python學習筆記 函式引數

剛開始學習python,看了一些資料,總結記錄一下基本的python函式引數。python中函式定義,有五種引數分類,分別為 位置引數 預設引數 可變引數 關鍵字引數 命名關鍵字引數。1 位置引數 也稱必選引數,也就是函式呼叫時,必須傳遞實參值。這類引數很簡單,如下,呼叫add函式時必須傳值給引數x...

Python學習筆記 Python函式引數

本人使用python已有一段時間,一直沒有時間進行系統學習,現在根據使用過程中記錄的問題,逐個尋找答案,並記錄至此。在使用python的過程中,不可避免的需要閱讀python原始碼,對其中的函式引數一直不是很明白,今天個人實踐一下。def func arg1,arg2 pass 這是我在編碼過程中寫...