【Python學習筆記】函數的參數問題

定義函數時,就肯定了函數名,必選參數個數和必選參數位置。因此函數頭其實就定義好了函數調用接口python

★★★★★★★★★★★★★★★★★★★★★★★★函數參數問題★★★★★★★★★★★★★★★★★★★★★★★★★★
函數除了正常定義的必選參數外,還可使用默認參數、可變參數和關鍵字參數,使得函數定義出來的接口,不但能處理複雜的參數,還能夠簡化調用者的代碼。數組

一、默認參數app

#!/usr/bin/env python
#-*- coding:utf-8 -*-
import math


# ★★★默認參數
def power(x):# 計算一個數的平方
    return x * x
print power(3)
def power3(x):# 計算一個數的三次方
    return x * x * x
print power3(3)
# 計算四次方、五次方。。。每次都寫一個函數,太麻煩了,因此能夠將power(x),改寫成power(x,n)計算x的n次方
def power(x, n):
    if n >0:
        m = 1
        while n > 0:
            n = n - 1
            m = m * x
        return m
    else:
	    return 0
print power(2,5)
# 此時又出現了一個問題,就是舊的power(x)失效了,再次調用報錯
# print power(2)
# 這時咱們就可使用默認參數了,將power(x,n)的第二個參數設置成默認參數2
def power(x, n = 2):
    if n >0:
        m = 1
        while n > 0:
            n = n - 1
            m = m * x
        return m
    else:
	    return 0
print power(2)		# 結果是4
print power(2,5)    # 結果是32
# 使用默認參數簡化了函數調用,下降了函數的難度,函數只須要定義便可

# ★使用默認參數時應注意:一、必選參數在前,默認參數在後,不然解釋器會報錯二、如何合理的設置默認參數
def enroll(name, gender):# 兩個必選參數
    n = name
    g = gender
    return n,g
print enroll('mike','M')
def enroll(name, gender, age = 6, city = 'NanJing'):# 兩個必選參數+兩個默認參數
    n = name
    g = gender
    a = age
    c = city 
    return n,g,a,c
print enroll('mike','M')
print enroll('mike','M',7)                    # 只有與默認參數不符時才須要提供想要的信息,
print enroll('mike','M',city = 'SuZhou') 
# ★也說明在有多個默認參數時,調用的時候,既能夠按順序提供默認參數(上上行),也能夠不按順序提供部分默認參數。當不按順序提供部分默認參數時,須要把參數名寫上(上行)

# ★★隱晦的錯誤:默認參數必須指向不變對象★★
def add_end1(L=[]):# L指向的是一個空的list
    L.append('END')
    return L
def add_end2(L=None):# L指向的是不可變對象None
    if L is None:
        L = []
    L.append('END')
    return L

運行效果:函數


★總結
爲何要設計str、None這樣的不變對象呢?由於不變對象一旦建立,對象內部的數據就不能修改,這樣就減小了因爲修改數據致使的錯誤。
 此外,因爲對象不變,多任務環境下同時讀取對象不須要加鎖,同時讀一點問題都沒有。咱們在編寫程序時,若是能夠設計一個不變對象,那就儘可能設計成不變對象
 設計

二、可變參數
上面碼過函數的必選參數,默認參數,這裏貼一下可變參數的內容code

可變參數,就是說函數參數的個數是可變的,能夠是0,1,2,,,任意多個
先考慮一下,若是參數個數可變,應該怎麼給它傳參,怎樣設計形參接收呢?[拓展:C#中函數對可變參數的處理]
想法:能夠是直接傳入一串參數或數組,而後用相似數組類型的形參接收
相似的,Python中,能夠傳入一個list或tuple,而後用list或tuple接收,也能夠直接傳入一串數字、list或list的元素、tuple或tuple的元素,而後用相似list和tuple的形參接收對象

#!/usr/bin/env python
#-*- coding:utf-8 -*-
import math


# ★★★可變參數

# 例:給定一組數字a,b,c……,請計算a^3 + b^3 + c^3 + ……
# ★將參數組成一個list或tuple。此時只是形式意義上的參數可變,並非可變參數
def sum_triple(numbers):
    sum = 0
    for n in numbers:
        sum += n * n * n
    return sum
print '1^3+2^3+...+6^3 = ', sum_triple([1,2,3,4,5,6])
print '1^3+2^3+...+6^3 = ', sum_triple((1,2,3,4,5,6))

# ★若是想要直接輸入一串數字,那就須要利用可變參數了,能夠簡化成以下
def sum_triple(*numbers):
    sum = 0
    for n in numbers:
        sum += n * n * n
    return sum
print '1^3+2^3+...+6^3 = ', sum_triple(1,2,3,4,5,6)
# 就是在參數前面加一個*,【本質上,numbers接收到的是一個tuple】

# ★若是數據已經在list或tuple中了,可採用如下方式調用可變參數
L = [1,2,3]
T = (1,2,3)
print '1^3+2^3+3^3 = ', sum_triple(L[0], L[1], L[2])
print '1^3+2^3+3^3 = ', sum_triple(T[0], T[1], T[2])
# ★因爲上述方式太繁瑣,因此也能夠採用在list或tuple變量前加一個*,將list或tuple變量的元素變成可變參數傳給函數
print '1^3+2^3+3^3 = ', sum_triple(*L)
print '1^3+2^3+3^3 = ', sum_triple(*T)

運行效果:接口

★總結:可變參數容許你傳入0個或任意個參數,這些可變參數在函數調用時自動組裝爲一個tupleip



三、關鍵字參數utf-8

上面碼過函數的必選參數,默認參數,可變參數
與可變參數相似:關鍵字參數容許傳入0個或任意個含參數名的參數,這些關鍵字-參數在函數內部自動組裝爲一個dict

#!/usr/bin/env python
#-*- coding:utf-8 -*-
import math


# ★示例,必選參數name,age+關鍵字參數keyword
def student(name, age, **keyword):
    print "name:",name,"age:",age,"keyword:",keyword

# ★只傳入必選參數
student(u'河海',100)

# ★傳入任意個數的關鍵字參數
student(u'河海', 100, city = 'NanJing', area = '500acre')

# ★和可變參數相似,若是已經存在一個dict,能夠把該dict轉換爲關鍵字參數傳進去:
kw = {'city': 'NanJing', 'area': '500acre'}
student(u'河海', 100, city=kw['city'], area=kw['area'])
# ★也能夠用簡化的寫法,將dict變量的元素對變成關鍵字參數傳給函數
student(u'河海', 100, **kw)

運行效果:
★總結:很明顯,它能夠擴展函數的功能
★應用:試想作一個用戶註冊的功能,除了用戶名和年齡是必填項外,其餘都是可選項,利用關鍵字參數來定義這個函數就能知足註冊的需求。就是說若是調用者願意提供更多的參數,咱們也能收到。

四、參數組合

在Python中定義函數,能夠用必選參數、默認參數、可變參數和關鍵字參數,這4種參數均可以一塊兒使用,或者只用其中某些
可是請注意,參數定義的順序必須是:必選參數、默認參數、可變參數和關鍵字參數。

#!/usr/bin/env python
#-*- coding:utf-8 -*-
import math


# ★參數組合
# 定義一個包含這四種參數類型的函數
def func(a, b, c=0, *args, **kw):
    print 'a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw
# 僅必選參數
func(1, 2)
a = 1 b = 2 c = 0 args = () kw = {}
# 必選參數+默認參數
func(1, 2, c=3)
a = 1 b = 2 c = 3 args = () kw = {}
# 必選參數+默認參數+可變參數
func(1, 2, 3, 'a', 'b')
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
# 必選參數+默認參數+可變參數+關鍵字參數
func(1, 2, 3, 'a', 'b', x=99)
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}
# 最神奇的是經過一個tuple和dict,你也能夠調用該函數:
args = (1, 2, 3, 4)
kw = {'x': 99}
func(*args, **kw)
a = 1 b = 2 c = 3 args = (4,) kw = {'x': 99}

運行效果:

★參數組合小結
在函數調用的時候,Python解釋器自動按照參數位置和參數名把對應的參數傳進去。
對於任意函數,均可以經過相似func(*args, **kw) 的形式調用它,不管它的參數是如何定義的

★★參數小結 默認參數必定要用不可變對象,若是是可變對象,運行會有邏輯錯誤! *args 是可變參數,args接收的是一個tuple;可變參數既能夠直接傳入: func(1, 2, 3) ,又能夠先組裝list或tuple,再經過*args 傳入: func(*(1, 2, 3))  **kw 是關鍵字參數,kw接收的是一個dict。關鍵字參數既能夠直接傳入: func(a=1, b=2) ,又能夠先組裝dict,再經過**kw 傳入: func(**{'a': 1, 'b': 2}) 。

相關文章
相關標籤/搜索