在學習函數之前,一直遵循:面向過程編程,即:根據業務邏輯從上到下實現功能,可以思考一下如果有某個功能的代碼是在多個地方使用的是否可以只寫一次?此時的程式碼該如何定義。先觀察以下的案例:
while True:
if cpu使用率> 90%:
#「發送郵件連接信箱 關閉連接
if 硬碟使用空間> 90%:
#傳送郵件提醒
關閉連線
if 記憶體佔用> 80 %:
#發送郵件提醒
連接郵箱伺服器
發送郵件##
#def 寄送郵件(內容)
#傳送郵件提醒
連接郵件伺服器
傳送郵件
關閉連線## 使用率> 90%:
發送郵件('CPU警報』)
對於上述的兩種實作方式,第二次必然比第一次的重複使用性和可讀性好,可以減少大量的程式碼量,減少開發時間,一處定義,多處調用,其實這就是函數式程式設計
函數式程式設計的概念:
開發程式時,需要某處程式碼多次使用,但為了提高編寫的效率以及程式碼的重用,所以把具有獨立功能的程式碼區塊組織為一個小模組,這就是函數
函數的定義和呼叫
<1>定義函數
定義函數的格式如下:
print ' 人生苦短,我用Python'
print '----------- --------------------------' 函數的定義主要有以下要點:
• def:表示函數的關鍵字 • 函數名稱:函數的名稱,呼叫時根據函數名稱呼叫函數
• 函數體:函數中進行一系列的邏輯計算或是該函數的功能內容。
• 參數:為函數體提供資料
<2>呼叫函數
#定義了函數之後,就等於有了一個具有某些功能的程式碼,想要讓這些程式碼能夠執行,需要呼叫它(注意在定義函數時裡面的內容不會執行)呼叫函數很簡單的,透過 函數名稱() 即可完成呼叫
demo:
# 定義完函數後,函數是不會自動執行的,需要呼叫它才可以 printInfo()
<3>函數的文件說明
範例:>>> def test(a,b):... "用來完成對2個數字求和"
.... print("%d"%(a+b))
...
>>> test(11,22)
33執行,以下程式碼
>>> help(test)
能夠看到test函數的相關說明
============ ====================================Help on function test in module __main__:
test(a, b)
用來完成對2個數字求和
(END)
=============================================
##
函數的參數-回傳值
<1>定義帶有參數的函數
範例如下:
def addnum(a, b):
c = a+b
c = a+b
c = a+b c = a+b
# print c
<2> 呼叫帶有參數的函數
以呼叫上面的add2num(a, b)函數為例:
def addnum(a, b):
c = a+b# print c##
## print c##
##add2num(11, 22) #呼叫帶有參數的函數時,需要在小括號中,傳遞資料
小總結:
• 定義時小括號內的參數,用來接收參數用的,稱為「形參」 • 呼叫時小括號中的參數,用來傳遞給函數用的,稱為「實參」
#ps:後面會有單獨一篇詳解函數參數的部落格
#<3> 帶有傳回值的函數
如下範例:
def add2num(a, b):
c = a+b
c = a+b
c
## 保存函數的回傳值範例如下: #定義函數
#def add2num(a, b):
#調用函數,順便保存函數的返回值###### ###result = add2num(100,98)####### ## ### ####因為result已經儲存了add2num的回傳值,所以接下來就可以使用了############ print result###### 結果:## # ###198###############在python中我們可以傳回多個值###### >>> def divid(a, b):# ## ... shang = a//b### ... yushu = a%b ### ... return shang, yushu### ...### >>>## ...### >>> divid(5, 2)### >>> sh### 5### >>> yu### 1#########本質上利用了元組#yu### 1############################################################################################################################家# ###########函數根據有沒有參數,有沒有回傳值,可以互相組合,一共有4種### • 無參數,無回傳值### • 無參數,無回傳值### • 有參數,無回傳值### • 有參數,有回傳值######### <1>無參數,無回傳值的函數### 此類函數,不能接收此類函數,不能接收參數,也沒有傳回值,一般情況下,列印提示燈類似的功能,使用這類的函數### <2>無參數,有傳回值的函數### 此類函數,不能接收參數,但是可以傳回某個數據,一般情況下,像採集數據,用此類函數### <3>有參數,無回傳值的函數### 此類函數,能接收參數,但不可以傳回數據,一般情況下,對某些變數設定資料而不需結果時,用此類函數### <4>有參數,有傳回值的函數### 此類函數,不僅能接收參數,還可以傳回某個數據,一般情況下,像數據處理並需要結果的應用,用此類函數######小總結############ • 函數根據有沒有參數,有沒有傳回值可以互相組合### • 定義函數時,是根據實際的功能需求來設計的,所以不同開發人員所寫的函數型別各不相同### • 一個函數到底有沒有回傳值,就看有沒有return,因為只有return才可以回傳資料### • 在開發中往往會根據需求來設計函數需不需要回傳值### • 函式中,可以有多個return語句,但是只要執行到一個return語句,那麼就表示這個函數的呼叫完成### •### 一個程式當中函數的名字盡量不要重複,當函數名字重複時後面的會把前面的覆蓋掉(注意:也不要與變數名稱重複同樣會被覆蓋)############函數的巢狀#######
def testB():
print('---- testB start----')
print('這裡是testB函數執行的程式碼...(省略)...')
print('---- testB end----')
#def testA():
print('---- testA start----')
testB( )
print('---- testA end----')
呼叫
# testA()
結果:
---- testA start----
---- testB start----
這裡是testB函數執行的程式碼...(省略)...
---- testB end----
---- testA end----
小總結:
• 一個函數裡面又呼叫了另外一個函數,這就是所謂的函數巢狀呼叫
• 如果函數A中,呼叫了另外一個函數B,那麼先把函數B中的任務都執行完畢之後才會回到上次函數A執行的位置
函數巢狀的案例:
1. 寫一個函數求三個數的和
2. 寫一個函數求三個數的平均值
# 求3個數的和
def sum3Number(a,b, c):
return a+b+c # return 的後面可以是數值,也可以是一個表達式
# 完成對3個數字求平均值
def average3Number(a,b,c):
## # 因為sum3Number函數已經完成了3個數的就和,所以只要呼叫即可
# 即把接收到的3個數,當做實參傳遞即可
sumResult = sum3Number(a,b,c)
aveResult = sumResult/3.0
# 呼叫函數,完成對3個數字求平均值
result = average3Number(11,2,55)
# print("average is %d"%result)
函數的局部變數、全域變數
#局部變數
範例: In [8]: def text1():
:
...: print("text1----%d" %a)
...:〠 300
.. .: print("text1----%d" %a)
...:
In [9]: def text2():## In [9]: def text2():## In [9]: def text2():## ## ...: print("text2-----%d" %a)
# # text1----200
修改後
總結
• 局部變量,就是在函數內部定義的變量
• 不同的函數,可以定義相同的名字的局部變量,但是各用個的不會產生影響
全域變數
## 概念:如果一個變量,既能在一個函數中使用,也能在其他的函數中使用,這樣的變數就是全域變數
範例:
# 定義全域變數
In [12]: a = 250
(): ...: print("----text1----%d" %a)
:
In [16]: text2()
----text2----250
當局部變數和全域變數重名當局部變數和全域變數重名的時候:
In [23]: a = 250 # 全域變數
In [24]: def 1(
In [24]: def 1( .: # 局部變數
...: "----text1----%d" %a)
. ..: # 局部變數
...: 〠 print("----text1----%d" %a)
...:
...: 〠("----text2----%d" %a) 〠# .:
In [26]: text1()
----11----666
----11----666
27]: text2()
----text2----250
In [28]:
• 在函數外邊定義的變數叫做全域變數 • 全域變數能夠在
所有
的函式中進行存取##•# 使用的是局部變數的,小技巧強龍不壓地頭蛇
In [31]: a = 250 In [32]: def text1():
...: a = 520
520 〠 〠 ---- a )
In [33]:
In [33]: def text2():
...:
global
a
...: a = 666 ...: print("----text2----%d" %a) ...:
##In#In#In#S#[3]#[3#[3]#[3#[3]# [#34]#[3#[3]#[3]#[3]#[3]# [#3]>沒有呼叫任何函數
In [35]: print(a)
250 In [36]:
〔 ## In [37]: text1()
----text1----520
In [38]: ---->
## In [39]: print(a)
250
In [40]: ## 1 ]:
# 呼叫text2
In [42]: text2()
----text2----666
----text2----666
---- 再次打印a
In [44]: print(a) 666
In [45]:
# 值已修改
總結:
• 如果在函數中修改全域變量,那麼就需要使用global進行聲明,否則相當於在(在沒有傳參數的情況)在函數內部重新定義了一個相同變數的物件
對於--可變類型的全域變數-和-不可變類型的全域變數-在函數內部修改的差異
ps:後面會有部落格詳細說明可變型別與不可變型別的概念
範例:------->不變類型: In [46]: a = 6 In [47]: def demo():# 1
...: print (a) ...: In [48]: demo() -------------------------------------------------- -----------
UnboundLocalError Traceback (most recent call1 71> in
----> ; 1 demo()
> 2 a += 1
3 print(a)
4
UnboundLocalError: local variable 'a' referenced before assignment
------------------------------- -------------------------------------------
註:顯然是不可以修改
------->可變類型:
In [49]: a = [1,]
In [50]:
In [50]: def demo():
〠 ...: print(a)
. ..:
[1, 2]
當呼叫函數時,在執行函數時在函數內部修改了列表的值--同時外部列印時也發生了變化。
總結:
○ 如果在函數中修改全域變量,那麼就需要使用global進行聲明,否則出錯
不使用glolod全域變數時不能修改全域變數的本質
是不能修改全域變數的指向,即不能將全域變數指向新的資料。 ○ 對於不可變類型
的全域變數來說,因其指向的資料不能修改,所以不使用global時無法修改全域變數。 ○ 對於可變類型
的全域變數來說,因其指向的資料可以修改,所以不使用global時也可修改全域變數。
以上是python中的基礎點的詳細內容。更多資訊請關注PHP中文網其他相關文章!