這篇文章給大家分享的是有關Python全棧開發之函數有什么用的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
所謂函數,就是把具有獨立功能的代碼塊組織為一個小模塊,在需要的時候調用
函數的使用有兩個步驟:
1、定義函數
2、調用函數
函數的作用,代碼重用,提高開發效率
def 函數名(): 函數封裝的代碼
def是英文define的縮寫
函數名稱應該能夠表達函數封裝代碼的功能,方便后續的調用
函數名稱的命名應該符合標識符的命名規則
通過函數名()即可完成函數的調用
def func(name): # name是形式參數
print(name) # 函數體
func('kernel') # 執行函數,'kernel'是實參定義了默認參數后,在函數調用時不再需要傳入,默認參數放在最后面
def info(name,age,country='China') # name,age是普通參數,country是默認參數
print('name:',name)
print('age:',age)
print('國家:',country)
info('kernel',21) # 調用時,沒有傳入country,就使用默認參數正常情況下,給函數傳遞參數需要按照定義的順序,不想按順序就要使用關鍵參數,但是關鍵參數必須放在普通參數之后
def info(name,age,country='China') # name,age是普通參數,country是默認參數
print('name:',name)
print('age:',age)
print('國家:',country)
info(age=21,name='kernel') # 使用關鍵參數,可以不按照順序*args
def demo(*args):
print(args) # ('kernel', 21, '山東')
demo("kernel",21,"山東")**kargs
def demo(**kwargs):
print(kwargs) # {'name': 'kernel', 'age': 21, 'address': '山東'}
demo(name="kernel",age=21,address="山東")特點:
函數內部調用自己
函數內部的代碼是相同的,只是參數不同,處理結果不同
當參數滿足一個條件時,函數不再執行
栗子
data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]
def binary_search(dataset,find_num):
if len(dataset) >1:
mid = int(len(dataset)/2)
if dataset[mid] == find_num: #find it
print("找到數字",dataset[mid])
elif dataset[mid] > find_num :# 找的數在mid左面
print("找的數在mid[%s]左面" % dataset[mid])
return binary_search(dataset[0:mid], find_num)
else:# 找的數在mid右面
print("找的數在mid[%s]右面" % dataset[mid])
return binary_search(dataset[mid+1:],find_num)
else:
if dataset[0] == find_num: #find it
print("找到數字啦",dataset[0])
else:
print("沒的分了,要找的數字[%s]不在列表里" % find_num)
binary_search(data,66)在函數中,針對參數使用賦值語句,會不會影響函數調用時的實參呢?
不會,只要針對參數使用賦值語句,無論是可變類型還是不可變類型,都會在函數修改參數的引用,不會影響到外部變量的引用
def demo(num, num_list):
print("start")
# 賦值語句
num = 200
num_list = [4,5,6]
print("id=%d,num=%d"%(id(num),num))
print("id=",id(num_list),"num_list=",num_list)
print("end")
gl_num = 100 # id=1875081376,gl_num=100
gl_list = [1,2,3] # id= 2164478175240 gl_list [1, 2, 3]
print("id=%d,gl_num=%d"%(id(gl_num),gl_num)) # id=1875084576,num=200
print("id=",id(gl_list),"gl_list",gl_list) # id= 2164477982152 num_list= [4, 5, 6]
demo(gl_num, gl_list)
print("id=%d,gl_num=%d"%(id(gl_num),gl_num)) # id=1875081376,gl_num=100
print("id=",id(gl_list),"gl_list",gl_list) # id= 2164478175240 gl_list [1, 2, 3]如果傳遞的參數是可變類型,在函數內部,使用方法修改了數據的內容,同樣會影響到外部的數據
def demo(name_list):
name_list.append('end')
print(name_list)
name_list = ['kernel']
print("id=",id(name_list),"name_list",name_list) # id= 1980496082376 name_list ['kernel']
demo(name_list)
print("id=",id(name_list),"name_list",name_list) # id= 1980496082376 name_list ['kernel', 'end']
demo(name_list)
print("id=",id(name_list),"name_list",name_list) # id= 1980496082376 name_list ['kernel', 'end','end']
我們發現,外部變量的數據已經被改變了,但是它的引用一直沒有改變
再看一個栗子
def demo(name_list=[]):
name_list.append('end')
print(name_list)
demo() # ['end']
demo() # ['end', 'end']
demo() # ['end', 'end', 'end']
demo() # ['end', 'end', 'end', 'end']
這不是我們想要的結果,那怎么辦呢?
我們只需要將形參改成一個不可變類型就可以了
def demo(name_list=None):
name_list = []
name_list.append('end')
print(name_list)
demo() # ['end']
demo() # ['end']
demo() # ['end']
demo() # ['end']滿足下列條件之一就可以稱為高階函數
存在一個參數為函數
函數的返回值中存在函數
map函數是Python內置的高階函數,它接收一個函數和一個可迭代對象,并將函數作用在可迭代對象的每個元素上,返回一個map對象
def func(x): return x * x r = map(func,range(10)) print(list(r)) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
reduce函數也是Python內置的高階函數,同樣它接收一個函數和一個可迭代對象,但是函數必須要接收兩個參數,reduce對可迭代對象的每個對象調用函數,并返回最終結果
栗子1 from functools import reduce def func(x,y): return x * y r = reduce(func,range(1,10)) print(r) 調用過程func(func(func(func(func(func(func(func(1,2),3),4),5),6),7),8),9) 栗子2 from functools import reduce def func(x,y): return x * y r = reduce(func,range(1,10),10) print(r) 調用過程func(func(func(func(func(func(func(func(func(1,10),2),3),4),5),6),7),8),9)
filter函數也是Python內置的高階函數,同樣它接收一個函數和一個可迭代對象,函數的作用是對每個元素進行判斷,返回True和False,filter根據判斷結果自動過濾掉不符合條件的元素
def func(x): if x % 2 == 0: return x r = filter(func,range(10)) print(list(r))
沒有函數名
單條語句
語句的執行結果就是返回值
name_list = ['kernel','alex','qiyue','hobby','eric','aomikee'] r = sorted(name_list) print(r) r = sorted(name_list,key=lambda x:len(x)) print(r)
內部函數
def outer():
print('outer is running。。。')
def inner():
print('inner is running。。。')
inner()
outer()
outer is running。。。
inner is running。。。
內部函數inner存在于outer函數作用域內部,所以如果在outer外部區域調用inner函數就會報錯關于閉包
def outer(): x = 10 y = 10 def inner(): print(x+y) return inner fun = outer() fun() # 20 如果試圖在一個內部函數里對外部函數的變量進行引用,這就是Python的閉包,由于閉包基于內部函數,所以閉包同樣不能在外部進行調用
修改外部函數的變量
def outer(): x = 10 y = 10 def inner(): x = x + 1 print(x+y) return inner fun = outer() fun() # UnboundLocalError: local variable 'x' referenced before assignment
因為閉包是基于內部函數的,所以說將會啟動Python解釋器的屏蔽機制,這時候Python解釋器就認為x是內部函數的局部變量,我們此舉正是試圖對不存在的變量進行修改操作,所以報在定義之前引用錯誤,那么,怎么解決這個問題呢
Python2
如果外部函數作用域的變量是可變類型的,那么它就不會被Python解釋器屏蔽掉 def outer(): x = [10] y = 10 def inner(): x[0] = x[0] + 1 print(x[0]+y) return inner fun = outer() fun() # 21
Python3
使用nonlocal關鍵字 def outer(): x = [10] y = 10 def inner(): nonlocal x x = x + 1 print(x+y) return inner
想想下面的程序會運行成功嗎?為什么?
for i in range(10): pass print(i) # 9 代碼執行成功,在Java/C#等強類型語言中,執行上面的語言會提示i沒有定義,而在Python中確是可以執行的,那是因為Python中沒有塊級作用域,代碼內的變量,外部可以調用
def say_hello():
name = 'kernel'
print('hello ',name)
print(name) # NameError: name 'name' is not defined
運行報錯,name變量只在函數中起作用,所以全局是無法調用的Python存在作用域鏈,首先從自己的作用域找,如果沒有就去一級一級的往上找,如果沒有找到就報錯
name = "Alex" def f1(): name = "Eric" def f2(): name = "Kernel" print(name) f2() f1() # Kernel
name = "kernel" def f1(): print(name) def f2(): name = "eric" f1() f2() # Kernel 為什么會輸入Kernel而不是eric呢? 那是因為函數在未執行時,作用域鏈就已經形成了,所以f1會去全局變量中找name這個變量而不是f2
r = ([lambda :x for x in range(10)]) print(type(r)) for i in r: print(type(i)) print(i()) 返回的結果是一個列表類型,列表的每個元素是一個函數,所有的函數運行出來都是9,為什么呢? 那是因為函數在沒有執行的時候,內部代碼是不會執行的
感謝各位的閱讀!關于“Python全棧開發之函數有什么用”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。