問題
你想定義乙個函式或者方法,它的乙個或多個引數是可選的並且有乙個預設值。
解決方案
定義乙個有可選引數的函式是非常簡單的,直接在函式定義中給引數指定乙個預設值,並放到引數列表最後就行了。例如:
def spam(a, b=42):
print(a, b)
spam(1) # ok. a=1, b=42
spam(1, 2) # ok. a=1, b=2
如果預設引數是乙個可修改的容程式設計客棧器比如乙個列表、集合或者字典,可以使用none作為預設值,就像下面這樣:
# using a list as a default value
def spam(a, b=none):
if b is none:
b =
...如果你並不想提供乙個預設值,而是想僅僅測試下某個預設引數是不是有傳遞進來,可以像下面這樣寫:
_no_value = object()
def spam(a, b=_no_value):
if b is _no_value:
print('no b value supplied')
...我們測試下這個函式www.cppcns.com:
>>> spam(程式設計客棧1)
no b value supplied
>>> spam(1, 2) # b = 2
>>> spam(1, none) # b = none
>>>
仔細觀察可以發現到傳遞乙個none值和不傳值兩種情況是有差別的。
討論定義帶預設值引數的函式是很簡單的,但絕不僅僅只是這個,還有一些東西在這裡也深入討論下。
首先,預設引數的值僅僅在函式定義的時候賦值一次。試著執行下面這個例子:
>>> x = 42
>>> def spam(a, b=x):
... print(a, b)
...>>> spam(1)
1 42
>>> x = 23 # has no effect
>>> spam(1)
1 42
>>>
注意到當我們改變x的值的時候對預設引數值並沒有影響,這是因為在函式定義的時候就已經確定了它的預設值了。
其次,預設引數的值應該是不可變的物件,比如none、true、false、數字或字串。 特別的,千萬不要像下面這樣寫**:
def spam(a, b=): # no!
...如果你這麼做了,當預設值在其他地方被修改後你將會遇到各種麻煩。這些修改會影響到下次呼叫這個函式時的預設值。比如:
>>> def spam(a, b=):
... print(b)
... return b
...>>> x = spam(1)
>>> x
>>> x.append(99)
>>> x.append('yow!')
>>> x
[99, 'yow!']
>>> spam(1) # modified list gets returned!
[99, 'yow!']
>>>
這種結果應該不是你想要的。為了避免這種情況的發生,最好是將預設值設為none, 然後在函式裡面檢查它,前面的例子就是這樣做的。
在測試none值時使用 is 操作符是很重要的,也是這種方案的關鍵點。 有程式設計客棧時候大家會犯下下面這樣的錯誤:
def spam(a, b=none):
if not b: # no! use 'b is none' instead
b =
...這麼lsibuzhmbb寫的問題在於儘管none值確實是被當成false, 但是還有其他的物件(比如長度為0的字串、列表、元組、字典等)都會被當做false。 因此,上面的**會誤將一些其他輸入也當成是沒有輸入。比如:
>>> spam(1) # ok
>>> x =
>>> spam(1, x) # silent error. x value overwritten by default
>>> spam(1, 0) # silent error. 0 ignored
>>> spam(1, '') # silent error. '' ignored
>>>
最後乙個問題比較微妙,那就是乙個函式需要測試某個可選引數是否被使用者傳遞進來。 這時候需要小心的是你不能用某個預設值比如none、 0或者false值來測試使用者提供的值(因為這些值都是合法的值,是可能被使用者傳遞進來的)。 因此,你需要其他的解決方案了。
為了解決這個問題,你可以建立乙個獨一無二的私有物件例項,就像上面的_no_value變數那樣。 在函式裡面,你可以通過檢查被傳遞引數值跟這個例項是否一樣來判斷。 這裡的思路是使用者不可能去傳遞這個_no_value例項作為輸入。 因此,這裡通過檢查這個值就能確定某個引數是否被傳遞進來了。
這裡對 object() 的使用看上去有點不太常見。object 是python中所有類的基類。 你可以建立 object 類的例項,但是這些例項沒什麼實際用處,因為它並沒有任何有用的方法, 也沒有任何例項資料(因為它沒有任何的例項字典,你甚至都不能設定任何屬性值)。 你唯一能做的就是測試同一性。這個剛好符合我的要求,因為我在函式中就只是需要乙個同一性的測試而已。
C 有預設引數的函式
c 提供了簡單的函式從形參到實參取值的處理辦法,就是帶有預設引數的函式,這樣給形參乙個預設值,就不一定必須從實參取值了例如有一函式 int area int a 2,int b 3 若想要呼叫此函式就不用必須賦予引數可以使用預設引數如 area 也可以改變其中的乙個值,但是如果想要緊緊改變乙個值的話...
C (帶有預設引數的函式引數)預設函式引數
預設引數?在c 中,允許實參的個數與形參的個數不同。在宣告函式原型時,為乙個或者多個形參指定預設值,以後呼叫這個函式時,若省略某乙個實參,c 則自動的以預設值作為相應引數的值。實列說明 includeusing namespace std int add int x 4,int y 7 int ma...
Python定義函式預設引數
慕課網 定義函式的時候,還可以有預設引數。例如python自帶的 int 函式,其實就有兩個引數,我們既可以傳乙個引數,又可以傳兩個引數 int 123 123 int 123 8 83int 函式的第二個引數是轉換進製,如果不傳,預設是十進位制 base 10 如果傳了,就用傳入的引數。可見,函式...