Python自動化開發學習3
函數
通過函數,可以定義一段代碼塊,之後通過函數名可以反復調用
定義一個函數:
def alert(): "打印Hello World" print("Hello World")
使用def來定義函數,第二行建議使用使用文檔字符串進行函數說明。
之後使用函數名就能夠反復調用函數。
alert()
函數的返回值
函數的最後可以使用return定義返回值,沒用retrun或者return後面不帶表達式,返回值都是None。一上面的函數為例
def alert(): "打印Hello World" print("Hello World") return # 這行有和沒有都一樣,之後可以去掉這行再試一下 a = alert() # 調用函數,並把返回值賦值給a print(a) # 來看一下a是不是None
有返回值的情況,返回值應該可以是任意類型,並且可以返回多個值
def test1(): print("This is test1") return 0 def test2(): print("This is test2") return 1,"Hello",["Sunday","Monday"],{"name":"Bob"} a = test1() b = test2() print(a) print(b)
返回多個值的情況,應該也是按一個值來處理的。這裏看到最終結果是將所有的值放到一個元組裏來作為返回值。
返回值的總結:
return數量=0:返回None
return數量=1:返回object
return數量>1:返回tuple
函數的參數
定義一個帶參數的函數
def alert(msg): "打印msg,如果是字符串返回1,否則返回0" print(msg) return 1 if type(msg) is str else 0 a = alert(123) # 調用函數時,也必須帶上參數 print(a) # 返回是0,因為是數字不是字符串 b = alert("123") print(b) # 返回是1,參數是字符串
形參:變量只有在被調用時才分配內存單元,在調用結束時,即刻釋放所分配的內存單元。因此,形參只在函數內部有效。函數調用結束返回主調用函數後則不能再使用該形參變量
實參:可以是常量、變量、表達式、函數等,無論實參是何種類型的量,在進行函數調用時,它們都必須有確定的值,以便把這些值傳送給形參。因此應預先用賦值,輸入等辦法使參數獲得確定值
def power(x,y): "計算x的y次方並返回" return(x**y) a,b = 3,2 c = power(a,b) print(c)
上面函數中的x和y就是形參。而後面調用函數時的a和b就是實參。
關鍵參數
上面調用函數時應用的參數必須一一對應,數量和位置都不能錯。也可以用關鍵參數來引用。
def power(x,y): "計算x的y次方並返回" return(x**y) a,b = 3,2 c = power(y=a,x=b) print(c)
也可以這樣混用,但是關鍵參數必須在位置參數後面
def power(x,y): "計算x的y次方並返回" return(x**y) a,b = 3,2 c = power(a,y=b) print(c)
參數a是位置參數,值傳給了x;剩下的y=b是關鍵參數,b的值也能傳給y。
默認參數
看一個默認參數的例子:
def introduce(name,age,country="China"): print("My name is %s"%name) print("I am %d years old"%age) print("I am from %s"%country) introduce("Jack",23) introduce("Jack",23,"Amarica")
如果定義函數的時候給參數預先賦了值,那麽這個參數就有了默認參數。在調用的時候可以省略這個默認參數,如果省略就取默認值,如果有值就使用調用的值
其他運用場景:默認安裝路徑,連接服務的默認端口號
非固定參數
定義函數時,可以使用*args和**kwargs。這樣在調用函數的時候,多余的實參會傳入這2個形參裏。
def test1(x,*args): # *args會把多傳入的參數變成一個元組 print(x,args) test1(1,2,3,4,5) test1(1,*[2,3,4,5]) # 也可以用這種形式調用 def test2(x,*args,**kwargs): # **kwargs會把多傳入的關鍵參數變成一個字典 print(x,args,kwargs) test2(1,2,3,a=4,b=5) test2(1,*[2,3],**{‘a‘:4,‘b‘:5}) # 也可以用這種形式調用
這裏*和**後面理論上可以使用任意的符合變量命名規則的名字,但是建議使用固定的名字*args和**kwargs。
局部變量和全局變量
在子程序中定義的變量稱為局部變量,在程序中定義的變量稱為全局變量。
全局變量作用域是整個程序,局部變量作用域是定義該變量的子程序。
當全局變量與局部變量同名時:在定義局部變量的子程序內,局部變量起作用;在其它地方全局變量起作用。
name = "Alice" # 先定義2個全局變量 age = 23 def test1(): print(name,age) # 這裏的2個變量還是全局變量 def test2(): name = "Jerry" # 這裏定義了局部變量name,對全局變量並沒有影響 print(name,age) # 這裏的name就是局部變量,age還是全局變量 test1() test2() print(name,age) # 這裏的2個全局變量的值並沒有改變
所以在子程序中既可以使用全局變量也可以使用自己的局部變量。如果全局變量和局部變量同名的情況下,改變局部變量也不會影響到全局變量。
但是如果想在子程序用改變全局變量,可以通過global聲明。
name = "Alice" # 先定義2個全局變量 age = 23 def test2(): global name # 聲明name是全局變量 name = "Jerry" # 這裏改變了name的值,看看全局變量是否也變了 print(name,age) print(name,age) # 先打印2個全局變量 test2() # 調用一次函數,其中修改了name print(name,age) # 這裏的全局變量也被修改了
方法能實現,但是盡量不用這麽用,不要在子程序中改變全局變量,更不要去定義全局變量。
最後再看一下列表在子程序中的情況,列表、字典、集合這類數據類型沒有局部變量。
name = [‘Alice‘,‘Bob‘,‘Carl‘] # 定義全局變量 def test(): print(name[1]) name[1] = "Jack" # 修改數組的一個元素 print(name) # 先打印一次數組 test() # 調用函數,函數中改變了數組中的一個元素 print(name) # 雖然函數中未使用global,但是數組中的元素還是被改變了
遞歸
在函數內部,可以調用其他函數。如果一個函數調用的是其自身,那麽這個函數就是遞歸函數。
遞歸的特性:
必須有一個明確的結束條件
每次進入更深一層遞歸時,問題規模相比上次遞歸都應有所減少
遞歸效率不高,遞歸層次過多會導致棧溢出。(Python最多遞歸999層,到了會報錯)
遞歸的例子:
def halve(n): "每次減半並轉為整形,直到0為止" print(n) n = int(n/2) if n > 0 : halve(n) halve(100)
高階函數
變量可以指向函數,函數的參數能接收變量。另外,一個函數也可以接收另一個函數作為參數,這種函數就稱之為高階函數。舉例說明:
def fxy(x,y,f): "返回x和y經過f函數處理之後的值" return f(x,y) a = fxy(3,6,min) # min是內置函數,求最小值 b = fxy(3,6,max) # max是內置函數,求最大值 c = fxy(3,6,pow) # pow是內置函數,求冪。3的6次方是729 print(a,b,c)
作業
工資管理系統
Alex 100000
Rain 80000
Egon 50000
Yuan 30000
-----以上是info.txt文件-----
實現效果:
從info.txt文件中讀取員工及其工資信息,最後將修改或增加的員工工資信息也寫入原info.txt文件。
效果演示:
1. 查詢員工工資
2. 修改員工工資
3. 增加新員工記錄
4. 退出
>>:1
請輸入要查詢的員工姓名(例如:Alex):Alex
Alex的工資是:100000。
1. 查詢員工工資
2. 修改員工工資
3. 增加新員工記錄
4. 退出
>>:2
請輸入要修改的員工姓名和工資,用空格分隔(例如:Alex 10):Alex 10
修改成功!
1. 查詢員工工資
2. 修改員工工資
3. 增加新員工記錄
4. 退出
>>:3
請輸入要增加的員工姓名和工資,共空格分割(例如:Eric 100000):Eric 100000
增加成功!
1. 查詢員工工資
2. 修改員工工資
3. 增加新員工記錄
4. 退出
>>:4
再見!
Python自動化開發學習3