Python 函數(shù)那不為人知的一面
通常我們定義一個(gè)函數(shù),然后調(diào)用該函數(shù)時(shí),函數(shù)相關(guān)的代碼才開(kāi)始執(zhí)行??墒呛芏嗳瞬⒉恢?,當(dāng)我們定義函數(shù)時(shí),一些代碼就開(kāi)始執(zhí)行了。今天就來(lái)說(shuō)說(shuō)函數(shù)這個(gè)不為人知的一面。
先看一段代碼:
- def do_something(opt: print('參數(shù) opt'), arg=print('參數(shù) arg')) -> print('函數(shù)的返回值'):
- print("do something runing")
- if __name__ == '__main__':
- pass
上面的代碼我們定義來(lái)一個(gè)函數(shù),但是并沒(méi)有調(diào)用它,那么它會(huì)輸出信息嗎?
會(huì)的,參數(shù)里無(wú)論是類(lèi)型提示部分,還是默認(rèn)賦值部分,還是返回值的類(lèi)型提示,里面的語(yǔ)句都會(huì)被執(zhí)行,結(jié)果如下:
這個(gè)做法我自己是很少見(jiàn)的。把 print 函數(shù)換成打開(kāi)文件、連接數(shù)據(jù)庫(kù)之類(lèi)的操作,也都會(huì)被執(zhí)行。
不過(guò)通常情況下,參數(shù)都是不可變類(lèi)型,如果傳入可變類(lèi)型,可能每次的函數(shù)調(diào)用,其結(jié)果都會(huì)被改變,例如:
- def do_something(opt: print("參數(shù) opt"), arg=[]) -> print("函數(shù)的返回值"):
- print("do something runing")
- print(f"{arg = }")
- arg.append(0)
- if __name__ == "__main__":
- do_something(opt=1)
- do_something(opt=1)
運(yùn)行結(jié)果如下:
可以發(fā)現(xiàn),調(diào)用兩次函數(shù) do_something,雖然并沒(méi)有傳入 arg 參數(shù),arg 的值已經(jīng)發(fā)送了變化。如果不注意這點(diǎn),可能會(huì)有 bug 發(fā)生。在 Pythcarm 中,會(huì)警告我們 arg 是可變對(duì)象:
如果要獲取函數(shù)的類(lèi)型提示、默認(rèn)值,可以這樣:
- def do_something(opt: 1, arg=2) -> 3:
- print("do something runing")
- print(f"{arg = }")
- arg.append(0)
- if __name__ == "__main__":
- print(f"{do_something.__annotations__ = }")
- print(f"{do_something.__defaults__ = }")
- #do_something.__annotations__ = {'opt': 1, 'return': 3}
- #do_something.__defaults__ = (2,)
本文轉(zhuǎn)載自微信公眾號(hào)「Python七號(hào)」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系Python七號(hào)公眾號(hào)。