定義一個函數
語法:
def 函數名():
函數的代碼
#def是英文define的縮寫
#函數名稱應該能夠表達函數封裝代碼的功能,方便後續的調用
#函數名稱的命名應該符合標識符的命名規則
可由字母,下劃線和數字組成
不能以數字開頭
不能與關鍵字重名
可以定義一個由自己想要功能的函數,以下是簡單的規則:
- 函數代碼塊以 def 關鍵詞開頭,後接函數標識符名稱和圓括號()。
- 任何傳入參數和自變量必須放在圓括號中間。圓括號之間可以用於定義參數。
- 函數的第一行語句可以選擇性地使用文檔字符串—用於存放函數說明。
- 函數內容以冒號起始,並且縮進。
- return [表達式] 結束函數,選擇性地返回一個值給調用方。不帶表達式的return相當於返回 None。
def jia(x,y): #函數名:jia,傳入參數x和y
''' #函數註釋
函數用來計算x+y
:param x:數字1
:param y:數字2
:return: x+y
'''
print(x+y) #函數內容
return #結束函數,返回none
使用函數的優點
-
代碼重用
-
保持一致性
-
可擴展
調用函數
定義一個函數只給了函數一個名稱,指定了函數裏包含的參數,和代碼塊結構。
這個函數的基本結構完成以後,你可以通過另一個函數調用執行,也可以直接從Python提示符執行。
def printme( str ):
"打印傳入的字符串到標準顯示設備上"
print (str)
return
printme( '這是一個字符串' )
>>這是一個字符串
函數參數
參數的作用
函數,把具有獨立功能的代碼塊組織成爲一個小模塊,在需要的時候調用
函數的參數,增加函數的通用性,針對相同的數據處理邏輯,能夠適應更多的數據
1.在函數內部,把參數當作變量使用,進行需要的數據處理
2.函數調用時,按照函數定義的參數順序,把希望在函數內部處理的數據,通過
參數傳遞
實參,形參
形參: 定義函數時,小括號中的參數,是用來接收參數使用的,
在函數內部,是當作變量來使用的
實參: 調用函數時使用,小括號中的參數,是用來把數據傳地到函數內部的
'''
函數參數的使用
在函數名後面的小括號內填寫 參數
多個參數之間使用 , 分隔
'''
# 定義函數時的變量,叫形參 形參可以任意起名字
def jia(x,y): #函數名:jia,形參:x和y
''' #函數註釋
函數用來計算x+y
:param x:
:param y:
'''
print(x+y)
# 在調用函數時傳遞得參數稱爲實參(真實的數據信息)
jia(1,2)
參數類型:
位置參數,關鍵字參數,默認參數,參數組
注意:
(1)位置實參調運,形參和實參是一一對應
(2)關鍵字參數調運,與形參位置無關。
(3)關鍵字參數不能寫在位置參數之前。
(4)位置參數和關鍵字參數同時存在,以位置參數調運爲主。
- 位置參數,關鍵字參數
def text(x,y):
print(x,end=" ")
print(y)
text('x','y') #位置實參調運,形參和實參是一一對應,實參不能大於形參數目
text(y=2,x=4) #關鍵字參數調運,與形參位置無關
#關鍵參數不能寫在位置參數之前 如 text(x=1,3)
text(3,y=2) #位置參數和關鍵字參數同時存在,以位置參數調運爲主
>>
x y
4 2
3 2
- 默認參數
def text(x,y,z):
print(x)
print(y)
print(z)
text (2,3) #調運函數的時候,默認參數非必須傳遞
>>
23z #參數在不修改其值的情況下,使用默認值
- 參數組
- *args : 接受N個位置參數,轉化成元組的形式
def test(*args): #傳遞參數組,只能傳遞位置參數
print(args) #輸出的結果就是一個元組
print(args[0]) #使用元組的方法,取第0個元素
test("zhangsan","18") # 位置參數
>>
('zhangsan', '18')
zhangsan
test("zhangsan","22","linux","120")
>>
('zhangsan', '22', 'linux', '120')
zhangsan
test(['1','2','linux'],'zhangsan','111','')
>>
(['1', '2', 'linux'], 'zhangsan', '111', '')
['1', '2', 'linux']
- **kwargs::接受N個關鍵字參數,轉化成字典的形式
def test1(**kwargs): #傳遞關鍵字參數,把關鍵字轉化字典
print(kwargs)
print(kwargs.values()) #調運字典的方法.輸出字典的值
test1(name = "zhangsan",age="18",hight='175')
>>
{'name': 'zhangsan', 'age': '18', 'hight': '175'}
dict_values(['zhangsan', '18', '175'])
可將關鍵字或者字典傳遞,並得到一個字典的輸出結果。
def test(name,age=8,**kwargs):
print(name)
print(age)
print(kwargs)
test("張三",age=18,hight='175',live='china')
>>
張三
18
{'hight': '175', 'live': 'china'}
函數返回值
- 沒有指定返回值,系統默認返回none
- 定義多個值:返回一個元組
- 定義一個值:返回對應數字類型的值
- 指定一個函數:返回該函數執行結果
- 指定一個函數名:返回函數的內存對象
import time
def time_text():
'''
# 該函數用來打印系統時間
# :return: 0
'''
time_format = "%Y-%m-%d %X" #:+函數內容
time_current = time.strftime(time_format)
print(time_current,end=" ") #end換行,以 分割
return 0
def text1(): #定義函數,函數名text1
time_text()
print('text1')
return "一個值"
def text1():
time_text()
print('text1')
return "一個值" #定義一個值:返回對應數字類型的值
print(text1())
>
2020-04-21 18:05:10 text1
一個值
def text1():
time_text()
print('text1')
return "一個值,兩個值,三個值","[1,2,3,4]",(1,2,3) #定義多個值:返回一個元組
print(text1())
>>
2020-04-21 20:06:21 text1
('一個值,兩個值,三個值', '[1,2,3,4]', (1, 2, 3))
def text2():
time_text()
print('text2')
return time_text() #返回time_text()值
text2()
>>
2020-04-21 20:08:28 text2
2020-04-21 20:08:28 #將time_text的結果返回
def text2():
time_text()
print('text2')
return time_text #指定一個函數名:返回函數的內存對象
print(text2())
>>
2020-04-21 20:13:37 text2
<function time_text at 0x000002399CE69598>
變量
局部變量
def change_name(name):
print("before change",name)
name = "Auliu" #局部變量,這個函數就是變量的作用域(作用與局部)
print("after change",name)
change_name('anliu')
>>
before change anliu
after change Auliu
全局變量
school = "xiyunkeji" #全局變量
def change_name(name):
school = "baiyijishu" #在函數內是不能修改全局變量的值,只能作用於局部
print("before change",name,school)
name = "Auliu" #局部變量,這個函數就是變量的作用域
print("after change",name)
change_name('anliu')
print(school)
>>
before change anliu baiyijishu #局部變量修改
after change Auliu #局部變量修改
xiyunkeji #全局變量依舊不變
- 在函數中修改全局變量
- 當全局變量爲列表,字典,集合包括類,這種複雜的數據類型及數據結果時,可以直接修改
names = ["劉二壯","李四","張三"]
def change_name():
names[0] = "李雲龍" #修改劉二壯爲李雲龍
print(names)
change_name()
print(names)
>>
['李雲龍', '李四', '張三'] #修改成功,並作用於全局
['李雲龍', '李四', '張三']
定義global之後,全局變量也是可以在函數內修改
name = '李壯'
def change_name():
global name #定義global後可在函數內修改全局變量
name = "劉虎"
print(name)
change_name()
print(name)
>>
劉虎
劉虎
遞歸函數
定義:在函數內部,可以調運其他函數。如果一個函數在內部調運自身,這個函數就是遞歸函數。
特性:
- 必須要有一個明確的結束條件。
- 每次進入更深的一層遞歸時,問題規模相比上次都應有所減少。
- 遞歸效率不高,遞歸層次過多會導致棧溢出(在計算機中,函數調運是通過棧(stack)來實現的,每當進入一個函數調運,棧就會加一層棧幀。每當函數返回,棧就會減少一層棧幀。由於棧的大小不是無限的,所以,遞歸調運的次數過多,會導致棧溢出)
def test(n):
print(n)
if int(n/2)>0: #相比上一層,規模減小
return test(int(n/2)) #返回本函數,內部調用自身
print("不滿足條件時的n",n)
test(15)
>>
15
7
3
1
不滿足條件時的n 1
高階函數
- 一個函數調用結果可以作爲參數被另一個函數傳遞
- 把一個函數名當做實參傳遞給另一個函數
def text(x,y):
z = x+y
return z
def text1(x,y):
z =x+y
print(z)
text1(text(2,5),5) #text1調用了text的運行結果作爲自己的一個實參。
>>
12
def bar():
print("This is bar")
return 0
def fun(bar): # 把一個函數名當做實參傳遞給另一個函數
print(bar())
fun(bar)
>>
This is bar
0
函數嵌套
定義:在一個函數體內定義另一個函數
def text ():
print("函數第一層")
def text2 ():
print("函數第二層")
text2()
text()
>>
函數第一層
函數第二層
裝飾器
定義:是用於拓展原來函數功能的一種函數,這個函數的特殊之處在於它的返回值也是一個函數,使用python裝飾器的好處就是在不用更改原函數的代碼前提下給函數增加新的功能。
原則:
- 不能修改被裝飾函數的源代碼。
- 不能修改被裝飾的函數的調運方式。
源代碼
import time
def func():
print("hello")
time.sleep(1)
print("world")
記錄下這個函數執行的總時間
簡陋裝飾器
#既不需要侵入,也不需要函數重複執行
import time
def deco(func):
def wrapper():
startTime = time.time()
func()
endTime = time.time()
msecs = (endTime - startTime)*1000
print("time is %d ms" %msecs)
return wrapper
@deco
def func():
print("hello")
time.sleep(1)
print("world")
if __name__ == '__main__':
f = func #這裏f被賦值爲func,執行f()就是執行func()
f()
#簡陋裝飾器,不使用任何語法糖和高級語法,這是裝飾器最原始的面貌
裝飾器
#帶有參數的裝飾器
import time
def deco(func):
def wrapper(a,b):
startTime = time.time()
func(a,b)
endTime = time.time()
msecs = (endTime - startTime)*1000
print("time is %d ms" %msecs)
return wrapper
@deco
def func(a,b):
print("hello,here is a func for add :")
time.sleep(1)
print("result is %d" %(a+b))
if __name__ == '__main__':
f = func
f(3,4)
#func()
這裏的deco函數就是最原始的裝飾器,它的參數是一個函數,然後返回值也是一個函數。其中作爲參數的這個函數func()就在返回函數wrapper()的內部執行。然後在函數func()前面加上@deco,func()函數就相當於被注入了計時功能,現在只要調用func(),它就已經變身爲“新的功能更多”的函數了。
所以這裏裝飾器就像一個注入符號:有了它,拓展了原來函數的功能既不需要侵入函數內更改代碼,也不需要重複執行原函數
帶參裝飾器
#帶有不定參數的裝飾器
import time
def deco(func):
def wrapper(*args, **kwargs):
startTime = time.time()
func(*args, **kwargs)
endTime = time.time()
msecs = (endTime - startTime)*1000
print("time is %d ms" %msecs)
return wrapper
@deco
def func(a,b):
print("hello,here is a func for add :")
time.sleep(1)
print("result is %d" %(a+b))
@deco
def func2(a,b,c):
print("hello,here is a func for add :")
time.sleep(1)
print("result is %d" %(a+b+c))
if __name__ == '__main__':
f = func
func2(3,4,5)
f(3,4)
#func()
多個裝飾器
#多個裝飾器
import time
def deco01(func):
def wrapper(*args, **kwargs):
print("this is deco01")
startTime = time.time()
func(*args, **kwargs)
endTime = time.time()
msecs = (endTime - startTime)*1000
print("time is %d ms" %msecs)
print("deco01 end here")
return wrapper
def deco02(func):
def wrapper(*args, **kwargs):
print("this is deco02")
func(*args, **kwargs)
print("deco02 end here")
return wrapper
@deco01
@deco02
def func(a,b):
print("hello,here is a func for add :")
time.sleep(1)
print("result is %d" %(a+b))
if __name__ == '__main__':
f = func
f(3,4)
#func()
'''
this is deco01
this is deco02
hello,here is a func for add :
result is 7
deco02 end here
time is 1003 ms
deco01 end here
'''