Python函數參數學習筆記

來源:互聯網
上載者:User

標籤:注意   不能   方式   導致   複雜   形式   問題   定義   iss   

在學習python函數參數的時候,發現python函數有多種參數形式,感覺有必要記錄一下,弄懂它們之間的區別和使用,主要參考了廖雪峰的python基礎教程:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431752945034eb82ac80a3e64b9bb4929b16eeed1eb9000

1、位置參數

例如:求xn

def power(x, n):    s = 1    while n > 0:        n = n - 1        s *= x    print(s)power(3, 4)  # 81power(4, 3)  # 64

可見,調用函數時,傳入的值按照順序依次賦給了x、n

在調用函數的時候,有多少個位置參數,就必須傳入多少個值,否則會報錯

power(3)
TypeError: power() missing 1 required positional argument: ‘n‘

提示power()函數缺少1個需要的位置參數‘n‘,從這兒也可以看出,位置參數是依次傳值的

2、預設參數

預設參數:在函數定義的時候,直接指定參數的值

def power(x, n=2):    s = 1    while n > 0:        n = n - 1        s *= x    print(s)

在本例中,power()函數給定了預設參數n=2,這種情況下,如果我們僅僅需要調用power()函數求一個數x的平方,在調用該函數時,就可以只傳入x的值

power(3)  # 9

如果我們想調用power()函數求x的4、5、6...次方的話,就可以通過給預設參數傳入值的方式

power(3, 4)  # 81

可見,預設參數能夠簡化函數的調用,這在一個函數的某些參數在多數情況下不需要改變時非常有用。比如:列印一個班級學生的姓名(name),年齡(age)和籍貫(city)資訊

通常來講,一個班級的同學的籍貫都是同一地區的,如果每次調用都要傳入city參數,會使調用變得複雜,這個時候,可以將city參數設定成預設參數

def student(name, age, city=‘chongqing‘):    print(‘name:‘, name)    print(‘age:‘, age)    print(‘city:‘, city)student(‘fzp‘, 7)

輸入結果:

name: fzpage: 7city: chongqing

設定預設參數時,需要注意一下幾點:

  1)必選參數必須在前,預設參數在後

  2)當函數有多個參數時,把變化大的放在前面,變化小的參數放後面。變化小的參數就可以作為預設參數

   好處:降低調用函數的難度

  3)當有多個預設參數時,可以按順序賦值,也可使用參數名直接賦值

對於第3點:

def student(name, age, city=‘chongqing‘, gender=7):    print(‘name:‘, name)    print(‘age:‘, age)    print(‘city:‘, city)    print(‘gender:‘, gender)student(‘frm‘, 7, ‘chengdu‘, 6)    #依順序賦值student(‘fzp‘, 7, gender=7)  #給gender參數賦值為7,這種情況下,city參數仍是預設的‘chongqing’

預設參數的一個典型問題,使用的時候需要注意:

def func(lis=[]):    lis.append(1)    print(lis)func() #[1]func() #[1, 1]

"這是因為解譯器執行函數定義時,預設參數值lis也被計算了,即[],因為預設參數lis也是一個變數,它指向對象[],每次調用該函數,如果改變了lis的內容,則下次調用時,預設參數的內容就變了,不再是函數定義時的[]了"引用廖大的解釋

對於該問題,我的理解是在執行append()方法時,只是往lis裡面添加了新的元素,並未改變其地址

lis = []print(id(lis)) #2293538950856lis.append(1)print(id(lis)) #2293538950856

解決該問題,可以用None這個不變對象來實現:

def func(lis=None):    if lis is None:        lis = []    lis.append(1)    print(lis)func() #[1]func() #[1]

"為什麼要設計strNone這樣的不變對象呢?因為不變對象一旦建立,對象內部的資料就不能修改,這樣就減少了由於修改資料導致的錯誤。此外,由於對象不變,多任務環境下同時讀取對象不需要加鎖,同時讀一點問題都沒有。我們在編寫程式時,如果可以設計一個不變對象,那就盡量設計成不變對象"

  1、不可變對象:字串(string)、(數值型number)、元組(tuple)、集合(set)
  2、可變對象:字典型(dictionary)、列表型(list)

3、可變參數

可變參數:傳入的參數個數可變

例:給定一組數字a,b,c……,請計算a2 + b2 + c2 + ……,要定義出這個函數,我們必須確定輸入的參數。由於參數個數不確定,我們首先想到可以把a,b,c……作為一個list或tuple傳進來,這樣,函數可以定義如下:

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

在調用該方法的時候,需要先組裝出一個list或tuple

print(result([1, 2, 3]))  #14print(result((1, 2, 3, 4)))  #30

如果用可變參數的話,就可以直接傳入參數,不需要先對參數進行組裝,可變參數用*標識

def result(*numbers):    sum = 0    for n in numbers:        sum += n * n    return sumprint(result(1, 2, 3, 4))  #30  直接給result函數傳值tup = (1, 2, 3)print(result(*tup)) #14  也可以傳入一個list或tuple,但需要在其前面加上*符號,否則會報錯:TypeError: can‘t multiply sequence by non-int of type ‘tuple‘ 
4、關鍵字參數

關鍵字參數:允許傳入任意個(包括0個)含參數名的的參數,這些參數在函數內部會自動組裝成一個dict,關鍵字參數用**標識

def student(name, age, **kwargs):    print(‘name:‘, name, ‘age:‘, age, ‘other:‘, kwargs)

可見,student函數除了必選參數name和age外,還可接受關鍵字參數kwargs,在調用該函數的時候,可以只傳入必選參數

student(‘fzp‘, 24)

輸出結果為:

name: fzp age: 24 other: {}

從結果也可以看出,關鍵字參數在函數內部自動組裝成了一個dict,此處,關鍵字參數未傳值,所有是一個空字典{}

關鍵之參數傳值可採用 ‘key‘ = ‘value‘ 的形式

student(‘fzp‘, 24, address=‘chongqing‘, sex=‘man‘)

輸出結果為:

name: fzp age: 24 other: {‘address‘: ‘chongqing‘, ‘sex‘: ‘man‘}

當然,關鍵字參數傳值可以直接傳入一個dict

dic = {‘address‘: ‘chongqing‘, ‘sex‘: ‘man‘}student(‘fzp‘, 24, **dic)

輸出結果為:

name: fzp age: 24 other: {‘address‘: ‘chongqing‘, ‘sex‘: ‘man‘}

注意:

1、kwargs獲得的dict僅僅是dic的一個拷貝,對kwargs的改變不會影響函數外面的dic

2、直接傳入一個dict時,要在之前添加**,否則會將整個dict識別為一個位置參數,如下:

student(‘fzp‘, 24, dic)  
TypeError: student() takes 2 positional arguments but 3 were given
 命名關鍵字參數

對於關鍵字參數,函數的調用者可以傳入任意不受限制的關鍵字參數。但是,又是我們或許想要限定關鍵字參數的名字,這時,就需要用到命名關鍵字參數

仍以student函數為例,如果只想接受address和sex為參數,可定義如下:

def student(name, age, *, address, sex):    print(‘name:‘, name, ‘age:‘, age, ‘address:‘, address, ‘sex:‘, sex)

和關鍵字參數**kwargs不同,命名關鍵字參數需要一個特殊分隔字元**後面的參數被視為命名關鍵字參數

調用方式如下:

student(‘fzp‘, 23, address=‘chongqing‘, sex=‘man‘)

輸入結果:name: fzp age: 23 address: chongqing sex: man

注意:命名關鍵字參數必須給值,至於為什麼有了必傳的位置參數,還要有必傳的命名關鍵字參數,我覺得主要有兩點原因:

  1、命名關鍵字參數通過指定參數名稱的方式,可以明確當前參數的含義

  2、命名關鍵字參數不必像位置參數那樣按順序傳值,時傳值更加靈活

當然,命名關鍵字參數可以有預設值,這樣,在調用的時候,就不必給其傳入值了:

def student(name, age, *, address, sex=‘man‘):    print(‘name:‘, name, ‘age:‘, age, ‘address:‘, address, ‘sex:‘, sex)

調用該函數:

student(‘fzp‘, 23, address=‘chongqing‘)

輸出結果為:name: fzp age: 23 address: chongqing sex: man
5、參數組合

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

舉例:

def func(a, b, c=3, *args, address, **kwargs):    print(‘a:‘, a, ‘b:‘, b, ‘c:‘, c, ‘args:‘, args, ‘address:‘, address, ‘kwargs:‘, kwargs)

調用該函數:

func(1, 2, 3, 4, 5, address=‘cq‘, d=‘char‘, e=‘dict‘)

輸入結果為:a: 1 b: 2 c: 3 args: (4, 5) address: cq kwargs: {‘d‘: ‘char‘, ‘e‘: ‘dict‘}

通過一個tuple和dict,也可以調用上述函數:

tup = (1, 2, 3, 4, 5)kw = {‘address‘: ‘cq‘, ‘ax‘: ‘sg‘}func(*tup, **kw)

輸出結果為:

a: 1 b: 2 c: 3 args: (4, 5) address: cq kwargs: {‘ax‘: ‘sg‘}

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

 

Python函數參數學習筆記

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.