前往
大廳
主題

從零開始的python ep.9 自訂函式(function)

黑子 | 2021-06-10 10:00:02 | 巴幣 1004 | 人氣 552

函式,如其名"括許多程式碼的一行程"
學會函式之後就可以進入下下章的模組了 (模組可以把函數整合,也可利用pygame做出一系列小遊戲)

先來介紹函式基本架構跟使用規則
def 是函式的起手式,函式定義就從def 開始
後面的get_answer是你定義的函示名稱,( )裡面的counting是參數,可以隨意取名字
之後冒號換行,下一行要記得縮排,這樣才會在你定義的函示底下工作,total_counter是函式的程式碼
total_counter 區域變數,當函式執行的過程它會短暫出現,並且完成你所賦予的程式要求的工作
利用簡單的加法來進行,並且在最後用return給出一個回傳值,在這之後你想print counting或是total_counter 都是得不到東西 的
實際測試結果如下
可以看到正常輸入數字式沒問題的,但是輸入字母或是字串,就會讓get_answer 壞掉
所以我們要進一步的了解到,函式中有參數跟引數
剛剛輸入的70跟100+200都是引數(來自共用空間),counting則是參數(在函式中的區域變數)



接著舉個例子,如果我想得到從1加到n的函式,要怎麼寫呢
可以用梯形公式來做(上底加下底乘高除以二)
但我們這邊是程式練習,就直接用for迴圈來做


上面提過,如果自訂的函式括號內有參數,如果使用時沒有填入,就會造成錯誤
舉例來說
因為我給了名字跟年齡有預設值,所以即使使用者輸入時沒有給值,依然可以正常顯示
另外如果沒有按照順序輸入,但只要輸入name="誰",age=多少,還是可以正常對應
但是如果不給user id,就會跳出錯誤,原因上面提過了
一般來說,我們不會使用函式中使用print,只用return來傳出回傳值就好
print 我們在函式在進行操作比較好



接著介紹python的特殊功能,在自訂的函式中,可以使用多種參數之外,也能利用
return產生多個回傳值(以tuple形式呈現)
舉例來說,我想同時得到,從一加到n跟n!以及n的平方,我可以這樣寫

當我輸入10,可以得到下方結果
實際看起來return還是只回傳了一個值(tuple),但其實包含了多個值


除了回傳值可以多個,參數的部分也可以使用不固定數量的參數
只要在參數前面加上(*)星號,就可以了,*nums 就是指括號內不定個數的引數都會執行函式的內容
可將*nums 視為一個容器
輸入五個數字,會分別得到第一個加到第三個,以及第四跟第五的總和

進階的使用方式,如果有多個不固定數量的參數,舉例如下
**Data 可以視作字典形式的容器(所以會有對應的值,像是uid就是key值,等於後面就是value)

當我輸入(黑字)
因為有if 幫忙判斷特定 key (uid,name,age) 是否有在data這個臨時字典中,所以像May沒有輸入年齡,不會跳出錯誤,Dany沒有id跟年齡同理不會跳出錯誤。



基本架構了解之後,就要進一步去檢查自己設計的參數跟引數是不是合理,要避免使用者輸入不合理的引數導致函式不能運作,所以在公司進行程式開發就會有專門進行QC的部門,常用的就是unittest (python要自己寫,微軟的話有專門的unittest可以直接使用)

這裡以高中大家所熟知的排列組合作舉例,如果箱子裡有三種不同顏色的球進行抽取,那我有可能一次抽出四顆球嗎? 想也知道是不行的,所以可以透過在函式中增加 if 來避免問題產生
範例:
def P(n,m):
ans=1
if m>n:
return 0
if n>m:
for i in range(m):
ans*=(n-i)
return ans
n=int(input())
m=int(input())
print(P(n,m))
這樣做就可以避免上述的問題(就是幫函式加上一個保險絲的概念)
另外當我們在函式中要使用到容器時,因為容器是在全域空間中存在,當我們把一個特定容器進行排序,增減,就會影響到原本容器的樣子。
但是如果是函式中的參數(區域變數),則不會影響到我們所使用的變數,以下舉例
X=2,X是程式裡的全域變數,在函式中的A是區域變數,當我們把X丟進func這個函式裡,並不會改變X本身。
區域變數只在它所定義的區塊內有效,當執行的程式離開了該區塊,所有於區塊內定義的自動變數就不存在了。
所以我們在編寫程式時要養成好習慣,不同的函式可以使用相同名稱的參數(區域變數),但是全域變數最好不要跟區域變數的名稱重複,避免參用時造成混淆
那如果一定要透過函式改變全域變數可行嗎? 答案是可行的,在C語言的環境,就是因為函式中本來應該要正常使用參數傳遞,但因為使用者偷懶省略傳遞這個步驟,導致全域變數的濫用,所以python直接讓函式只能讀,不能改全域變數,如果想知道怎麼改,請見下一章。


然後還要注意回傳值跟參數型態的一致性,傳統語言中不論是輸入還是輸出型態都會給定,但python靈活的特性,導致我們可以寫出單一型態的輸入,不同型態的輸出(如數字 字串 容器等等),會讓使用者不知道這個函式到底是怎麼運作的,這點務必切記
額外補充 https://softnshare.com/facebook-pyretool/ (關於靜態檢查工具)

下一章的篇幅會比較短,算是補充的小章節,本來想跟這一章合併,但本章內容真的有點偏多,就拆開成兩章吧。




送禮物贊助創作者 !
0
留言

創作回應

紅蓮
請問%是什麼意思?我google也找不到這種用法
2021-09-09 20:25:54
黑子
https://home.gamer.com.tw/artwork.php?sn=5100201 可以參考這篇
2021-09-10 15:59:20

更多創作