Python函數中的引數(必需引數、關鍵字引數、預設引數和不定長引數)

2020-07-16 10:05:26
Python 中函數的引數可細分為必需引數、關鍵字引數、預設引數和不定長引數四種情況。

必需引數是指為了確保函數正確執行,需要明確賦值的引數。例如定義一個列印輸入的字串的函數:
def print_string(str):
    print(str)
    return

若呼叫該函數時不對引數 str 賦值:
print_string()

則 Python 執行時環境將報錯,上述程式碼的執行結果如下所示:

>>> def print_string(str):
...          print(str)
...          return

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


關鍵字引數則是指在傳參時指明形參的名稱,並為其賦以實參的值,例如下面計算長方形面積的函數:
def Calc_Area(width, height):
    return width * height
    print(Calc_Area(height=4, width=3))
上述程式碼的執行結果如下所示:

>>> def Calc_Area(width, height):
...          return width * height

>>> print(Calc_Area(height=4, width=3))
12


預設引數是指為函數的引數取一個預設值,當呼叫函數時可以不傳入具有預設值的引數,當執行函數時使用該預設值參與運算。例如為計算長方形面積的函數的 height 引數指定預設值並呼叫:
def Calc_Area(width, height = 5):
    return width * height
    print(Calc_Area(3))
上述程式碼的執行結果如下所示:

>>> def Calc_Area(width, height = 5):
...         return width * height

>>> print(Calc_Area(3))
15


有的函數在定義時無法指明所有的引數,或是在呼叫時傳入的引數個數比定義時的多,這就需要用到不定長引數。不定長引數主要有兩種傳入方式,一種是在引數名稱前加星號*,以元組型別匯入,用來存放所有未命名的變數引數。例如:
def Multi_Add(arg1, *args):
    sum = 0
    for var in args:
        sum += var
    return arg1 + sum
    print(Multi_Add(1, 2, 3 , 4))
Multi_Add( ) 函數的作用是將輸入的引數相加,上述程式碼的執行結果如下所示:

>>> def Multi_Add(arg1, *args):
...         sum = 0
...         for var in args:
               sum += var
...         return arg1 + sum

>>> print(Multi_Add(1, 2, 3 , 4))
10
>>> print(Multi_Add(1, 2, 3 , 4, 5, 6))
21


另一種是在引數名稱前加兩個星號**,以字典型別匯入,用來存放所有命名的變數引數,例如:
def fun(**kwargs):
    for key, value in kwargs.items():
        print("{0} 喜歡 {1}" . format (key, value))
    fun (我="貓", 貓="盒子")
上述程式碼的執行結果如下所示:

>>> def fun(**kwargs):
...         for key, value in kwargs.items():
...         print("{0} 喜歡 {1}" . format (key, value))
       
>>> fun (我="貓", 貓="盒子")
我 喜歡 貓
貓 喜歡 盒子


在 Python 中一切變數都是物件,數位、字串和元組是不可更改(immutable)的物件,列表、字典等則是可以更改(mutable)的物件。所謂不可更改的意思是改變變數的取值實際上是新生成一個同型別的變數並賦值。

例如,變數賦值 a=1,然後改變其取值 a=2,實際是新生成一個 int 型別的物件 2,再讓 a 指向它,而 1 則被丟棄,相當於新生成了 a。所謂可以更改則是真正改變了變數內部的一部分取值。例如,變數賦值 list=[1,2,3],然後改變其取值 list[1]=6,實際上是更改了其元素的值,本身 list 沒有變化,只是其內部部分元素的值被修改了。

當不可更改物件作為函數引數時,類似於 C、C++ 等語言中的值傳遞,傳遞的只是引數的值,並不會影響該不可更改物件本身。例如:
def changeVar(a):
    a = 1
    b = 2
    changeVar(b)
    print(b)
上述程式碼的執行結果如下所示:

>>> def changeVar(a):
...          a = 1

>>> b = 2
>>> changeVar(b)
>>> print(b)
2


當可更改物件作為函數引數時,類似於 C、C++ 等語言中的參照傳遞,是將該物件本身傳過去,在函數體內修改了該物件的內容後,其內部元素的值將被真正修改。例如:
def changeVar2(l):
    l.append([3, 4])
    print ("函數內取值:", l)
    return

l = [1, 2]
changeVar2(l)
print ("函數外取值:", l)
上述程式碼的執行結果如下所示:

>>> def changeVar2(l):
...          l.append([3, 4])
...          print ("函數內取值:", l)
...          return

>>> l = [1, 2]
>>> changeVar2(l)
函數內取值: [1, 2, [3, 4]]
>>> print ("函數外取值:", l)