<04day>_函數嵌套--閉包函數--裝飾器--叠代器--生成器
一、函數的嵌套定義
1、python函數支持嵌套
def f1(): #f1函數的定義 def f2(): #f2函數的定義 print(‘from f2‘) def f3(): #f3函數的定義 print(‘from f3‘) f2() f1()
嵌套函數--運行結果說明:
1首先調用f1()結果,f1函數為空。擔保函f2函數,f2函數有內容打印並且有調用,f2函數包含f3函數,但f3函數無調用。
運行結果:
列子:多個數據之間的大小比較。
#!/usr/bin/python # -*- coding:utf-8 -*- # Author:zhaosj def max2(x,y): return x if x>y else y def max4(a,b,c,d): res1 = max2(a,b) res2 = max2(res1,c) res3 = max2(res2,d) return res3 print(max4(12,88,19,33)) # max4(12,88,19,33)把4個數值傳參數給max4(a,b,c,d)
輸出結果:
二、函數、名稱空間與作用域
1、名稱空間:全局名稱空間、局部名稱空間;
2、全局名稱空間:文件的執行會產生全局名稱空間,指的是文件級別定義的名字;
文件級別有:
x = 1、if x == 1:、import time.....
3、局部名稱空間:調用函數時會產生局部名稱空間,只在函數調用時臨時綁定,調用結束,綁定即結束。
""" x = 1000 # 全局名名稱空間 def func(): x = 1 # 局部名稱空間 def f1(): pass """
三、閉包函數
閉包函數:
1、內部包含函數;
2、引用外部作用域除全局作用域以外;
列:
#!/usr/bin/python # -*- coding:utf-8 -*- # Author:zhaosj def f1(): x = 1 def f2(): print(x) return f2 f = f1() print(f) print(f.__closure__[0].cell_contents)
#closure閉合的意思(只要是閉包函數,那麽次函數就有必合屬性。查看的值是一個元組,取出值.cell_contents)
輸出結果:
四、閉包函數的應用--惰性計算
1、利用閉包函數做爬蟲
2、導入一個模塊from urllib.request import urlopen(此模塊比較老,新爬蟲模塊為request)
from urllib.request import urlopen zhi = urlopen(‘http://www.baidu.com‘).read() print(zhi.decode(‘utf-8‘))# bytes類型想要看懂需要decode,轉換為utf-8
例子:
#!/usr/bin/python # -*- coding:utf-8 -*- # Author:zhaosj from urllib.request import urlopen def index(url): def get(): return urlopen(url).read() return get # 如果沒有return get 把值返回出來那麽只能在內部調用 oldboy = index(‘http://crm.oldboyedu.com‘) print(oldboy().decode(‘utf-8‘))
運行結果:
五、函數----《裝飾器》
1、裝飾器:修飾別人的工具,修飾添加功能,工具指的就是函數;
2、裝飾器本身可以是任何可調用對象,被裝飾的對象也是任意可調用對象;
無參函數裝飾器:
########################裝飾器################################## import time def timmer(func): def wrapper(*args,**kwargs): start_time=time.time() #func() # 原始index函數 res = func(*args,**kwargs) stop_time=time.time() print(‘run time is %s‘ %(stop_time-start_time)) return res return wrapper ####################被裝飾的函數################################# @timmer # index=timmer(index)),加上裝飾器,會打印出執行時間的內容 def index(): time.sleep(3) # 運行三秒在進行打印一下內容 print(‘歡迎登陸...‘) return 1 index() #函數調用 wrapper()
裝飾器的調用方式列如:@timmer 【 index=timmer(index))】
----------------------------------------------------------------------------------------
裝飾器:--用戶登錄認證:(文件的認證方式)__無參函數
#!/usr/bin/python # -*- coding:utf-8 -*- # Author:zhaosj ####################裝飾器######################################## def auth(func): def wrapper(*args,**kwargs): name = input(‘輸入用戶名>>:‘) password = input(‘輸入密碼>>:‘) if name == ‘zhaosj‘ and password == ‘123‘: print(‘\033[45m登陸成功[0m‘) res = func(*args,**kwargs) return res else: print(‘\033[45m登陸失敗\033[0m‘) return wrapper ########################函數功能區################################# @auth #裝飾器--函數調用 def index(): print(‘歡迎登陸首頁‘) @auth #裝飾器--函數調用 def home(name): print(‘%s 歡迎來到主頁面‘ %name) index() home(‘zhaosj‘)
運行結果:
裝飾器:--用戶登錄認證:(認證之後進入系統,做認證記憶)__無參函數
#!/usr/bin/python # -*- coding:utf-8 -*- # Author:zhaosj
# 定義全局變量,開始時無用戶登陸。默認狀態為沒有登陸狀態
login_user = {‘user‘:None, ‘status‘:False} ##############################裝飾器######################################### def auth(func): def wrapper(*args,**kwargs):
#判斷有沒有用戶登陸以及當前的登陸狀態,有用戶登錄則不再進行登陸認證
if login_user[‘user‘] and login_user[‘status‘]: res = func(*args,**kwargs) return res else: # 否則進行用戶登陸認證 name = input(‘輸入用戶名>>:‘) password = input(‘輸入密碼>>:‘) if name == ‘zhaosj‘ and password == ‘123‘: # 判斷輸入的用戶名以及密碼 login_user[‘user‘]=‘zhaosj‘ # 用戶登陸密碼--zhaosj login_user[‘status‘]=True # 用戶登陸狀態--True print(‘\033[45m登陸成功\033[0m‘) # 登陸成功 res = func(*args,**kwargs) # return res else: print(‘\033[45m登陸失敗\033[0m‘) return wrapper ###############################函數功能區######################################## @auth #裝飾器--函數調用 def index(): print(‘歡迎登陸首頁‘) @auth #裝飾器--函數調用 def home(name): print(‘%s 歡迎來到主頁面‘ %name) index() home(‘zhaosj‘)
運行結果:(登陸成功)
運行結果:(登陸失敗)
裝飾器:--用戶登陸認證:__裝飾器,有參函數
有參函數裝飾器只有3層,無參函數裝飾器只有2層
#!/usr/bin/python # -*- coding:utf-8 -*- # Author:zhaosj
# 定義全局變量,開始時無用戶登陸。默認狀態為沒有登陸狀態
login_user = {‘user‘:None, ‘status‘:False} #############################裝飾器####################################### def auth(driver = ‘file‘): def auth2(func): def wrapper(*args,**kwargs): if driver == ‘file‘: print(‘================file的認證‘) ###############################認證功能######################################
#判斷有沒有用戶登陸以及當前的登陸狀態,有用戶登錄則不再進行登陸認證 if login_user[‘user‘] and login_user[‘status‘]: res = func(*args,**kwargs) return res else: # 否則進行用戶登陸認證 name = input(‘輸入用戶名>>:‘) password = input(‘輸入密碼>>:‘) if name == ‘zhaosj‘ and password == ‘123‘: # 判斷輸入的用戶名以及密碼 login_user[‘user‘]=‘zhaosj‘ # 用戶登陸密碼--zhaosj login_user[‘status‘]=True # 用戶登陸狀態--True print(‘\033[45m登陸成功\033[0m‘) # 登陸成功 res = func(*args,**kwargs) # return res else: print(‘\033[45m登陸失敗\033[0m‘) ############################################################################## elif driver == ‘ldap‘: print(‘===================ldap的認證‘) elif driver == ‘mysql‘: print(‘===================mysql的認證‘) #return func(*args,**kwargs) else: print(‘===================未知認證方式‘) return wrapper return auth2 #############################函數功能區########################################### @auth(‘file‘) #裝飾器--函數調用 [email protected]====>index=auth2(index)====>index=wrapper】 def index(): print(‘歡迎登陸首頁‘) @auth(driver=‘mysql‘) #裝飾器--函數調用 def home(name): print(‘%s 歡迎來到主頁面‘ %name) index() #wrapper home(‘zhaosj‘)#wrapper(zhaosj)
運行結果:
六、叠代器
叠代器的概念:
重復的過程稱為叠代,每次重復即一次叠代,並且每次叠代的結果是下一次叠代的初始值;
1、叠代一個--<列表>
zhaosj_list = [0,1,2,3] count = 0 while count < len(zhaosj_list): print(‘=======>‘,zhaosj_list[count]) count += 1
運行結果:
2、叠代一個--<元組>
zhaosj_tulop = (0,1,2,3) count = 0 while count < len(zhaosj_tulop): print(‘========>‘,zhaosj_tulop[count]) count += 1
運行結果:
3、叠代--<字符串>
zhaosj_str = ‘zhaoshujing‘ count = 0 while count < len(zhaosj_str): print("============",zhaosj_str[count]) count += 1
運行結果:
為什麽需要叠代器?
對於沒有索引的數據類型(像:字典-dic、集合-set。就沒有索引)必須提供一種不依賴與索引的叠代方式
可叠代對象;
可叠代的對象:內置__iter__()方法的都是可叠代對象;
[1,2].__iter__() #列表 ‘zhaosj‘.__iter__() #字符串 (1,2).__iter__() #元組 {‘a‘:1,‘b‘:2}.__iter__() #字典 {1,2,3}.__iter__() #集合
叠代器:執行__iter__方法,得到的結果就是叠代器
叠代器:可執行__next__()方法的都是叠代器。
i = [1,2,3].__iter__() print(i) print(i.__next__()) # 每執行一次,就會取一次值(不能一次全取) print(i.__next__())
運行結果:
字典生成--叠代器--取出 字典中的值
dic = {‘a‘:1,‘b‘:2,‘c‘:3} i = dic.__iter__() #字典生成叠代器 print(i.__next__()) #next一次取出一個key print(i.__next__()) print(i.__next__())
字典生成--叠代器--後取出字典中的值
dic = {‘a‘:1,‘b‘:2,‘c‘:3} i = dic.__iter__() #字典生成叠代器 # 字典生成叠代器後取出字典中的值 while True: try: key = i.__next__() print(dic[key]) except StopIteration: # 異常處理,捕捉異常。遇到異常執行break break
運行結果:
查看一個字符串的長度
s = ‘hello‘ print(len(s)) # len(s) ===s.__len__()
運行結果:
七、生成器
生成器---生成器函數(只要函數體包含yield關鍵字,該函數就是生成器);
yield 與 return相似,但是return只執行一次就結束,yield只會暫時掛起;
yield 會把函數變成叠代器;
#!/usr/bin/python # -*- coding:utf-8 -*- # Author:zhaosj def foo(): print(‘first‘) yield 1 # 遇到yield掛起,返回參數。 print(‘second‘) yield 2 print(‘third‘) yield 3 print(‘fourth‘) yield 4 print(‘ffth‘) g = foo() #next(g) 觸發叠代器g的執行,進而觸發函數的執行 print(next(g)) print(next(g))
運行結果:
<04day>_函數嵌套--閉包函數--裝飾器--叠代器--生成器