一 函數的定義和調用python
def 關鍵字 函數名(設定與變量相同):
函數體閉包
例子app
1 #函數定義 2 def mylen(): 3 """計算s1的長度""" 4 s1 = "hello world" 5 length = 0 6 for i in s1: 7 length = length+1 8 print(length) 9 10 #函數調用 11 mylen()
二 函數的返回值return函數
1 1,遇到return,結束函數。 2 def func1(): 3 print(11) 4 print(22) 5 return 6 print(333) 7 print(444) 8 func1() 9 2,給函數的調用者(執行者)返回值。 10 無 return 返回None 11 return 不寫 或者 None 返回None 12 return 返回單個數. 13 return 返回多個數,將多個數放在元組中返回。 14 '''
1 沒有返回值spa
1 #函數定義 2 def mylen(): 3 """計算s1的長度""" 4 s1 = "hello world" 5 length = 0 6 for i in s1: 7 length = length+1 8 print(length) 9 10 #函數調用 11 str_len = mylen() 12 #由於沒有返回值,此時的str_len爲None 13 print('str_len : %s'%str_len) 14 15 沒有return
2 返回多個值日誌
1 # def my_len(): 2 # count = 0 3 # for i in s1: 4 # count += 1 5 # return 666,222,count,'老男孩' 6 # print(my_len(),type(my_len())) 7 8 9 10 # def my_len(): 11 # count = 0 12 # for i in s1: 13 # count += 1 14 # return 666,222,count 15 # ret1,ret2,ret3 = my_len() # (666, 222, 19,) 16 # print(ret1) 17 # print(ret2) 18 # print(ret3)
3 返回一個值code
1 #函數定義 2 def mylen(): 3 """計算s1的長度""" 4 s1 = "hello world" 5 length = 0 6 for i in s1: 7 length = length+1 8 return length 9 10 #函數調用 11 str_len = mylen() 12 print('str_len : %s'%str_len) 13 14 return返回一個值
三 函數的傳參orm
1 li = [1, 2, 3, 43, 'fdsa', 'alex'] 2 s1 = 'fdsgdfkjlgdfgrewioj' 3 4 # def my_len(a): # 函數的定義()放的是形式參數,形參 5 # count = 0 6 # for i in a: 7 # count += 1 8 # return count 9 # ret = my_len(li) # 函數的執行() 實際參數,實參 10 # print(ret) 11 # print(len(s1))
3.1 實參分爲:blog
位置參數。 必須一一對應,按順序
# def func1(x,y):
# print(x,y)
# func1(1, 2)
#2,關鍵字參數。必須一一對應,不分順序。
# def func1(x,y,z): # print(x,y,z) # func1(y=2,x=1,z=5,)
混合參數。一一對應 且 關鍵字參數必須在位置參數後面。
1 # def func2(argv1,argv2,argv3): 2 # print(argv1) 3 # print(argv2) 4 # print(argv3) 5 # func2(1,2,argv3=4)
3.2 形參分爲排序
#1,位置參數。 必須一一對應,按順序
# def func1(x,y): # print(x,y) # func1(1,2)
默認參數。 必須在位置參數後面。
1 # def register(name,sex='男'): 2 # with open('log1',encoding='utf-8',mode='a') as f1: 3 # f1.write("{} {}\n".format(name,sex)) 4 # register('aa')
動態參數 *args,**kwargs 萬能參數
# kwargs接收的只是鍵值對的參數,並保存在字典中
#args接收除去鍵值對之外的全部參數,保存成元組形式
1 ##動態參數 *args **kwargs 2 # def func2(*args,**kwargs): 3 # print(args) ##打印成元組 4 # print(kwargs) ##打印成字典 5 # func2(1,2,2,3,4,5,'alex','老男孩',a='ww',b='qq')
三種參數的混合排序
1 # def func3(a,b,*args,sex='男'): ##順序是 位置參數,*args ,默認參數 2 # print(a) 3 # print(b) 4 # print(sex) 5 # print(args) 6 # func3(1,2,'老男孩','alex',sex='女') 7 8 9 # def func4(a,b,*args,sex='男',**kwargs): ##位置參數,*args,默認參數,**kwargs 10 # print(a) 11 # print(b) 12 # print(args) 13 # print(sex) 14 # print(kwargs) 15 # func4(1,2,3,'alex','aa',sex='女',name='alex')
打散
1 # def func1(*args,**kwargs): 2 # print(args) 3 # print(kwargs) 4 # l1 = [1,2,3,4] 5 # l11 = (1,2,3,4) 6 # l2 = ['alex','wusir',4] 7 # func1(*l1,*l2,*l11) ##這個是以元組出現的 8 打印出來的結果:
(1, 2, 3, 4, 'alex', 'wusir', 4, 1, 2, 3, 4) 10 11 def func1(*args,**kwargs): 12 print(args) 13 print(kwargs) 14 dic1 = {'name1':'alex'} 15 dic2 = {'name2':'wusir'} 16 func1(**dic1,**dic2) ##出來的結果是以字典形式存在的
打印出來的結果:
{'name1': 'alex', 'name2': 'wusir'}
四 函數的命名空間和做用域
命名空間一共分爲三種:
全局命名空間
局部命名空間
內置命名空間
*內置命名空間中存放了python解釋器爲咱們提供的名字:input,print,str,list,tuple...它們都是咱們熟悉的,拿過來就能夠用的方法。
三種命名空間之間的加載與取值順序:
加載順序:內置命名空間(程序運行前加載)->全局命名空間(程序運行中:從上到下加載)->局部命名空間(程序運行中:調用時才加載)
取值順序:
在局部調用:局部命名空間->全局命名空間->內置命名空間
在全局調用:全局命名空間->內置命名空間
綜上所述,在找尋變量時,從小範圍,一層一層到大範圍去找尋。
做用域
做用域就是做用範圍,按照生效範圍能夠分爲全局做用域和局部做用域。
全局做用域:包含內置名稱空間、全局名稱空間,在整個文件的任意位置都能被引用、全局有效
局部做用域:局部名稱空間,只能在局部範圍內生效
4.1 命名空間
1 # name = 'wusir' ##全局命名空間 2 # age = 12 3 # def func1(): 4 # name1 = 'wusir' ##局部命名空間 5 # age1 = 34 6 # return name1 7 # print(func1()) 8 # print(name) 9 10 11 # name1 = 'wusir' 12 # def func1(): 13 # print(name1) 14 # def func2(): 15 # print('xxxxx',name1) 16 # func2() 17 # func1()
查看命名空間
1 # name1 = 'wusir' 2 # def func1(): 3 # name2 = 'laonanhai' 4 # print(globals()) ##查看全局變量 5 # print(locals()) ##查看局部變量 6 # func1()
4.2
##global 關鍵字 聲明全局空間,若是已經存在則更改
1 #global ##聲明一個全局變量(限於字符串,數字) 2 # name = 'wusir' 3 # def func1(): 4 # global name ##聲明一個全局變量 5 # name = 'alex' 6 # return 7 # func1() 8 # print(name) ##打印的結果是alex 9 10 11 12 #對可變數據類型(list,dict,set)能夠直接引用不用經過global。 13 # li = [1,2,3] 14 # dic = {'a':'b'} 15 # 16 # def change(): 17 # li.append('a') 18 # dic['q'] = 'g' 19 # print(dic) 20 # print(li) 21 # change() 22 # print(li) 23 # print(dic)
nonlocal ##1不能修改全局變量
#2在局部做用域中,對父級做用域(或者更外層做用域非全局做用域)的變量進行引用和修改,
# 而且引用的哪層,從那層及如下此變量所有發生改變
1 # def func2(): 2 # name1 = 'alex' 3 # print('+',name1) 4 # def inner(): 5 # nonlocal name1 6 # name1 = 'wusir' 7 # print('*',name1) 8 # def inner1(): 9 # pass 10 # inner() 11 # print('%',name1) 12 # func2()
4.3 函數名
1 # #1 能夠互相賦值 2 # def func1(): 3 # print(666) 4 # f1 = func1 5 # f1() 6 7 #2 函數名能夠當成函數的參數 8 # def func1(): 9 # print(777) 10 # def func2(argv): 11 # argv() 12 # print(999) 13 # func2(func1) 14 15 #能夠當成容器類數據類型的參數 16 # def func1(): 17 # # print(666) 18 # # def func2(): 19 # # print(777) 20 # # def func3(): 21 # # print(888) 22 # # ll = [func1,func2,func3] 23 # # for i in ll: 24 # # i() 25 26 27 #函數名能夠當成函數的返回值 28 # def func1(): 29 # print(666) 30 # def func2(argv): 31 # print(777) 32 # return argv 33 # ret = func2(func1) ##func2執行 而且把func1傳給了argv而argv又返回給了ret,因此ret=func1 34 # ret()
4.4 閉包
閉包 內層函數對外層函數非全局變量的引用,叫作閉包
#閉包的好處:若是python 檢測到閉包,
# 他有一個機制,你的局部做用域不會隨着函數的結束而結束
# def wrapper(): # name1 = '老男孩' # def inner(): # print(name1) # inner() # print(inner.__closure__) ##若是返回是cell是閉包 # wrapper() # name1 = '老男孩' # def wrapper(): # def inner(): # print(name1) # inner() # print(inner.__closure__) ##返回none不是閉包 # wrapper() name = 'alex' def wrapper(argv): def inner(): print(argv) inner() print(inner.__closure__) # cell wrapper(name)
五 裝飾器
裝飾器:在不改變原函數即原函數的調用的狀況下,
# 爲原函數增長一些額外的功能,打印日誌,執行時間,登陸認證等等。
5.1 最簡單的裝飾器
1 # # ##最簡單的裝飾器 2 import time 3 4 # def func1(): 5 # # print('hello world') 6 # # time.sleep(0.3) 7 8 # # def timer(f1): #f1 = func1 9 # # def inner(): 10 # # start_time = time.time() 11 # # f1() ##至關於執行func1() 12 # # end_time = time.time() 13 # # print('此函數的執行效率%s' %(end_time - start_time)) 14 # # return inner ##inner返回給了func1 15 # # func1 = timer(func1) 16 # # func1() ##執行inner()
5.2 @ 第二種裝飾器
1 # def timer(f1): 2 # def inner(): 3 # start_time = time.time() 4 # f1() 5 # end_time = time.time() 6 # print('此函數的執行效率是%s' % (end_time-start_time)) 7 # return inner 8 # 9 # @timer ##func1 = timer(func1) =inner 10 # def func1(): 11 # print('hello world') 12 # time.sleep(0.3) 13 # func1() ##至關於執行了inner() ,而後返回到上面 執行inner裏面的語句, 14 # @timer 15 # def func2(): 16 # print('你好,世界') 17 # time.sleep(0.4) 18 # func2()
5.3 #被裝飾的函數帶參數
1 # def timer(f1): ##f1 = func1 2 # def inner (*args,**kwargs): 3 # start_time = time.time() 4 # f1(*args,**kwargs) ##func1函數是在這步開始執行的func1(111,222) 5 # end_time = time.time() 6 # print('此函數的執行效率是%s' %(end_time-start_time)) 7 # return inner 8 # @timer #func1 = timer(func1) ##inner=func1 9 # def func1(a,b): 10 # print(a,b) 11 # print('hello world') 12 # time.sleep(0.9) 13 # func1(111,222) ##inner 把 111和222傳給了上面的inner(*args)
5.4 被裝飾的函數帶返回值
1 def timer(f1): 2 def inner(*args,**kwargs): 3 start_time = time.time() 4 ret = f1(*args,**kwargs) ##func1(111,222) 5 end_time = time.time() 6 print('此函數執行效率%s' % (end_time-start_time)) 7 return ret ##返回給了func1 8 return inner 9 @timer #func1 = timer(func1) 10 def func1(a,b): 11 print(a,b) 12 print('hello world') 13 time.sleep(0.4) 14 return 666 15 ret2 = func1(111,222) ##inner(111,222) 16 print(ret2)