如果在呼叫乙個函式時,沒有傳遞預設引數,則函式內的預設引數是對函式的預設引數屬性__defaults__的引用,
如
def func(arg1=):呼叫func時如果沒有傳參,上面的arg1就是func.__defaults__[0]的引用
沒傳遞預設引數,會發生以下情況
這樣在有些情況下會導致邏輯出錯的,例如
def func(arg1=):
if(arg1==):
'arg1 is empty
'
else
:
'arg1 is not empty
arg1
func() # arg1 is empty
func() #arg1 is not empty [1]
第二次呼叫func的時候,並沒有傳遞引數arg1,但是第一次呼叫時,函式內部已經修改了__defaults__
這是為啥呢?為何第二次呼叫不重置arg1為?
因為python的預設引數只會在函式定義時被確定,而不是每次呼叫時重新確定,所以,一旦在函式中修改了預設引數,則再隨後的呼叫中都會生效
由於有這個特性,在定義函式時,如果預設引數使用可變的物件型別,如上例子,則很可能導致邏輯出錯,
所以,如不是特別需要,則不允許在函式內部對預設引數引用的func.__defaults__屬性進行修改,如何能讓乙個物件不被修改?那就是在操作arg1前取消它對__defaults__的引用
以上例子改動一下
def func(arg1=):if(arg1==):
'arg1 is empty
'arg1=
else
:
'arg1 is not empty
'print arg1
上例中,在使用者沒有傳遞預設引數arg1時,函式內部會給arg1變數重新賦值,讓arg1去引用我們想用的物件,這樣arg1就不會修改func.__defaults__了
如果是預設引數是有值的情況,可以這樣操作
def func(arg1=[1,2,3]):if(arg1==[1,2,3]):
'is [1,2,3]
'arg1=[1,2,3] #
重點是這裡,取消arg1對__defaults__屬性的引用,防止arg1修改__defaults__
else
:
'not [1,2,3]
'print arg1
以上太囉嗦,下例模仿了python官方例子,使用不可變型別(例如none)作為預設引數,邏輯簡潔,推薦使用
定義時為none,但函式邏輯中進行進一步重新賦值為想使用的預設值
if to is
none:
to = [1,2,3]
return to
總結:防止預設引數修改函式的__defaults__,需要:
1.定義預設引數時,最好使用不可變型別.
2.如果預設引數一定要使用可變型別,那就在函式內部對預設引數重新賦值為可變型別的具體值.
Python定義函式預設引數
慕課網 定義函式的時候,還可以有預設引數。例如python自帶的 int 函式,其實就有兩個引數,我們既可以傳乙個引數,又可以傳兩個引數 int 123 123 int 123 8 83int 函式的第二個引數是轉換進製,如果不傳,預設是十進位制 base 10 如果傳了,就用傳入的引數。可見,函式...
python定義函式時預設引數注意事項
如果在呼叫乙個函式時,沒有傳遞預設引數,則函式內的預設引數是對函式的預設引數屬性 defaults 的引用,如呼叫func時如果沒有傳參,上面的arg1就是func.defaults 0 的引用 沒傳遞預設引數,會發生以下情況 這樣在有些情況下會導致邏輯出錯的,例如 func arg1 is not...
python定義函式時的引數 呼叫函式時的傳參
一 定義函式 1 位置引數 直接定義引數 2 預設引數 或者關鍵字引數 引數名 預設值 3 位置引數必須在預設引數之前 二 呼叫函式 1 按位置傳,直接寫引數的值 2 按關鍵字傳,關鍵字 值 3 位置引數必須在關鍵字引數之前 4 關鍵字引數可在 args和 kwargs之前 注 呼叫時,無論定義的函...