Python中函數參數的詳細介紹(附執行個體)

來源:互聯網
上載者:User
本篇文章給大家帶來的內容是關於Python中函數參數的詳細介紹(附執行個體),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所協助。

Python的函數定義比較簡單,藉助於關鍵字def進行實現,但是參數的靈活度卻非常大。除了正常定義的必選參數外,還可以使用預設參數、可變參數、關鍵字參數、命名關鍵字參數以及參數組合,這使得函數定義出來的介面,不僅能處理複雜的參數,還能簡化調用者的代碼

一、位置參數

在函數定義的時候,指定參數的位置順序。位置參數必須在被調用函數定義中的準確順序來進行傳遞。

例如:計算x的n次方

def powern(x,n):    s = 1    while n >0:        s = s * x        n = n -1    return s

x與n這兩個參數都是位置參數。調用函數時,必須傳入且傳入的兩個值按照位置順序依次賦給參數x和n,若預設,則會報錯。例如:

>>> powern(5)Traceback (most recent call last):File "<stdin>", line 1, in <module>TypeError: powern() missing 1 required positional argument: 'n'

二、預設參數

在函數定義中,為參數預先定義預設值。當在函數調用時,若沒有為參數提供指定值,則使用預設值。
例如:仍舊是求x的n次方,但是預設為x的3次方。

def powern( x,n = 3):    s = 1    while n >0:        s = s * x        n = n -1    return s

執行:powern(2),相當於調用powern(2,3)
如果要求2的四次方,則需要執行:powern(2,4)

設定預設參數的好處?
預設參數可以簡化函數的調用,降低調用函數的難度。無論是簡單調用還是複雜調用,函數只需定義一個。
例如上述powern()的例子,當傳入n的其他值時,則可以實現x的其他n次方。

但是在使用預設參數的時候,如果使用不當,也會有坑。先來瞭解一下可變參數和不可變參數作為函數參數時的不同:

不可變參數作為函數參數

>>> a = 1>>> def func(a):...     print('func_id:',id(a))...     a = 2...     print('after_func_id:',id(a),'id(2):',id(2))...>>> print('out_of_func_id:',id(a),'id(1):',id(1))out_of_func_id: 501962480  id(1): 501962480   # 全域變數a的id>>> func(a)            # 將全域參數a傳入函數func_id: 501962480    # a=1 的idafter_func_id: 501962496  id(2): 501962496  >>> print(a)            # 退出函數,a的值仍為11

當把全域a傳遞給函數後,函數自動複製一份引用。執行完a=2之後,id(a)的記憶體位址發生變化。但是跟外層的a沒有關係。

可變對象作為函數參數

>>> a = []>>> def func2(a):...     print('func2_id:',id(a))...     a.append(1)...>>> print('out_of_func2_id',id(a))out_of_func2_id 59694296>>> func2(a)func2_id: 59694296>>> print(a)[1]

變數a的類型為list,是可變對象。函數的引用指向的是可變對象,地址沒有發生變化,所以函數操作後,a的內容發生了改變。
所以當再次操作func2(a)函數時,產生跟預期不一樣的結果:

>>> func2(a)func2_id: 59694296    # a地址不變>>> print(a)[1, 1]        # 因為第一次執行func2(a)時,已經修改了a=[1],再次調用時,在[1]裡新增

例如:

def add_end( L=[] ):  # 設定為一個list變數L(對象可變)    L.append('end')    return L>>> add_end( )['end']>>> add_end()  ['end', 'end']

當連續重複使用預設參數調用時,結果出現錯誤。
Python函數在定義的時候,預設參數L的值就被計算出來了,即[]。L也是一個變數,它指向對象[],每次調用該函數,如果改變了L的內容,則下次調用時,預設參數的內容就變了,不再是函數定義時的[]了。
可以改為:

def add_end( L=None ):  # L為不變對象      if L is None:              L = []                L.append('end')       return L

則無論調用多少次,都不會出現問題。
所以,定義預設參數要牢記一點:預設參數必須指向不變對象!因為不變對象一旦建立,對象內部的資料就不能修改,這樣就減少了由於修改資料導致的錯誤。此外,由於對象不變,多任務環境下同時讀取對象不需要加鎖。

設定預設參數時,有幾點需要注意
一.必選參數在前,預設參數在後,否則Python的解譯器會報錯。
二.如何設定預設參數?當函數有多個參數時,把變化大的參數放前面,變化小的參數放後面。變化小的參數就可以作為預設參數。
三.不要使用可變對象作為預設參數。

三、可變參數*args

可變參數,即傳入的參數個數是可變的,0至任意個。
因為參數個數不確定,則可以使用一個list 或者tuple傳進來。之後在函數調用時會自動組裝為一個tuple。
例如:

def calc(numbers):  # 變數            sum = 0                   for n in numbers:               sum = sum + n * n       return sum            >>> calc( [1,2,3] )   # 傳入的是一個list14

利用可變參數 *args:

def calc( *numbers ):      sum = 0            for n in numbers:    # 在函數內部,numbers組裝成一個tuple    sum = sum + n * n    return sum>>> calc( )            # 0個參數  0>>> calc( 1,3,5,7 )    # 多個參數 84>>> num = [1,2,3]      # list>>> calc( *num )       # *list –> tuple14   >>> t = (1,3,5)>>> calc( t )          # tuple(錯誤)  Traceback (most recent call last):  File "<stdin>", line 1, in <module>  File "<stdin>", line 4, in calcTypeError: can't multiply sequence by non-int of type 'tuple'>>> calc( *t )                  35

函數代碼完全不變。但是,調用該函數時,可以傳入任意個參數,包括0個參數。

四、關鍵字參數**kw

關鍵字參數**kw允許傳入0個至任意個含參數名的參數,這些關鍵字參數在函數內部自動組裝為一個dict。例如:

def person(name , age , **kw ):    print('name:',name,'age:',age,'other:',kw)>>> person('xiong',18)name: xiong age: 18 other: {}>>> person('xiong',18,city = 'SH')          # city是原本沒有的參數,但是因為有**kwname: xiong age: 18 other: {'city': 'SH'}

關鍵參數有什麼用?可以擴充函數的功能。比如在person()函數裡面,可以保證接收到name和age這兩個參數。但是如果提供更多參數,也能收到。當然也可以先組裝一個dict,再把該dict轉換為關鍵字參數傳遞進去:

>>> extra ={'city':'shanghai','job':'SET'}                     # dict的定義>>> person('xiong',18,city = extra['city'],job=extra['job'])   # dict的使用name: xiong age: 18 other: {'city': 'shanghai', 'job': 'SET'}  # dict的內容>>> person('xiong',18,**extra)name: xiong age: 18 other: {'city': 'shanghai', 'job': 'SET'}

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

五、命名關鍵字參數

如果要限制關鍵字參數的名字,就可以用命名關鍵字參數。需要一個特殊分隔字元“”,“”後面的參數被視為命名關鍵字參數。如果缺少“*”,Python解譯器則無法識別位置參數和命名關鍵字參數。在調用時,必須指定參數名字與參數值。
例如,只接收city和job作為關鍵字參數,可以使用如下定義:

def person( name ,age,*,city,job):    print(name , age , city , job )>>> person('xiong', 18, city='shanghai', job='tester')xiong 18 shanghai tester

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

>>> def person( name,age,*args,city,job ):     # 此處city和job也是命名關鍵字參數...   print(name, age, city, job)

命名關鍵字參數必須傳入參數名,如果沒有傳入參數名,調用將會報錯:

>>> person('xlp',18,'shanghai','tester')          # 錯誤調用 Traceback (most recent call last):  File "<stdin>", line 1, in <module>TypeError: person() missing 2 required keyword-only arguments: 'city' and 'job'>>> person('xlp',18,city='shanghai',job='tester')  # 正確調用 xlp 18 shanghai tester

命名關鍵字參數可以有預設值,從而簡化調用:

>>> def person1(name,age,*,city='shanghai',job):...   print(name,age,city,job)...>>> person1('xlp',18,job='engineer')xlp 18 shanghai engineer

六、參數組合

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

【總結】

(1)定義可變參數和關鍵字參數的文法:
*args是可變參數,args接收的是一個list、tuple;
**kw是關鍵字參數,kw接收的是一個dict;
(2)調用函數時如何傳入可變參數和關鍵字參數的文法:
可變參數直接傳入:func(1,2,3)
可變參數間接傳入:先組裝成list或tuple,l=(1,2,3),再通過args傳入,func(l)
關鍵字參數直接傳入:func(a=1,b=2)
關鍵字參數間接傳入:先組裝成dict,d={‘a’:1,’b’:2},再通過kw傳入,func(d)
(3)命名關鍵字參數 是為了限制調用者可以傳入的參數名,同時可以提供預設值。
(4)定義命名的關鍵字參數在沒有可變參數的情況下,不要忘記寫分隔字元*,否則定義的將是位置參數

相關推薦:

Python中函數的可變參數

理解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.