一、有參裝飾器python
''' import time current_user={'user':None} def deco(func): def wrapper(*args,**kwargs): if current_user['user']: #已經登錄過 res = func(*args, **kwargs) #用戶已經登陸直接調用被裝飾的函數,不須要重複進行登陸 return res user=input('username>>: ').strip() pwd=input('password>>: ').strip() if user == 'egon' and pwd == '123': print('login successful') # 記錄用戶登錄狀態 current_user['user']=user #登陸成功記錄用戶的登陸狀態,而後調用被裝飾的函數 res=func(*args,**kwargs) return res else: print('user or password error') return wrapper @deco def index(): print('welcome to index page') time.sleep(1) @deco def home(name): print('welecome %s to home page' %name) time.sleep(0.5) index() home('egon') ''' # def f1(): # x=1 # def f2(): #裝飾器外在套一層函數,一般最多套三層 # def f3(): # print(x) # return f3 # return f2 # # f2=f1() # # f3=f2() # # f3() import time current_user={'user':None} #記錄用戶的登陸狀態 def auth(engine='file'): #接收函數體內部須要外部傳入的參數 def deco(func): #func接收被裝飾的函數不能改 def wrapper(*args,**kwargs): #wrapper(*args,**kwargs)接收被裝飾函數的的參數 if current_user['user']: #記錄用戶的登陸狀態,判斷用戶是否已經登陸 #已經登錄過 res = func(*args, **kwargs) #用戶已經登陸,則會直接調用被裝飾的函數 return res #拿到被裝飾函數的返回值,沒有返回值則返回None user=input('username>>: ').strip() pwd=input('password>>: ').strip() if engine == 'file': #engine即爲須要最外層函數傳入的值,不然會報錯 # 基於文件的認證 if user == 'egon' and pwd == '123': print('login successful') # 記錄用戶登錄狀態 current_user['user']=user #記錄用戶的登陸成功後的狀態 res=func(*args,**kwargs) #登陸成功後調用被裝飾的函數 return res #拿到被裝飾函數的返回值 else: print('user or password error') elif engine == 'mysql': print('基於mysql的認證') elif engine == 'ldap': print('基於ldap的認證') else: print('沒法識別認證來源') return wrapper return deco @auth(engine='file') # @deco #index=deco(index) #index=wrapper def index(): print('welcome to index page') time.sleep(1) @auth(engine='file') def home(name): print('welecome %s to home page' %name) time.sleep(0.5) index() home('egon')
二、迭代器mysql
''' 一、什麼是迭代器 迭代器即迭代取值的工具 迭代: 迭代是一個重複的過程,每一次重複都是基於上一次的結果而來的 單純的重複並非迭代 while True: print('1111') #單純的重複沒有基於上一次的結果 迭代: l=['a','b','c'] def iterator(item): i=0 while i < len(item): print(l[i]) i+=1 二、 爲何要有迭代器 基於索引的迭代器取值方式只適用於列表、元組、字符串類型 而對於沒有索引的字典、集合、文件,則不在適用 因此必須找到一種通用的而且不依賴於索引的迭代器取值方式=》迭代器 迭代器適用於可迭代的類型 三、如何用迭代器 ''' # l=['a','b','c'] # i=0 # while i < len(l): #使用while條件循環,每次基於上一次的結果而來,因此是迭代 # print(l[i]) # i+=1 # l = ['a', 'b', 'c'] # s='hello' # # def iterator(item): #item='hello' #將重迭代的過程,定義成一個函數,每次取不一樣數據類型的值,只須要傳參調用便可 # i = 0 # while i < len(item): # print(item[i]) # i += 1 # # iterator(l) #將列表當作參數傳入調用 # iterator(s) #將字符串當作參數傳入調用 # 可迭代的對象:在python中但凡內置有__iter__方法的對象都是可迭代的對象 # 字符串、列表、元組、字典、集合、文件都是可迭代的對象 # num1=10 # num2=10.1 # s1='hello' # l=[1,2,3] # t=(1,2,3) # d={'x':1} # s2={1,2,3} # f=open('a.txt','w') # # s1.__iter__ #如下數據類型及文件均內置有__iter__,因此都是可迭代對象 # l.__iter__ # t.__iter__ # d.__iter__ # s2.__iter__ # f.__iter__ # # # 迭代器對象:指的是既內置有__iter__方法,又內置有__next__方法的對象 #執行可迭代對象的__iter__方法獲得的就是內置的迭代器對象 # 文件對象--------------------------自己就是迭代器對象 #強調: #一、迭代器對象必定是可迭代的對象,反之則否則 # info={'name':'egon','age':18,'is_beautiful':True,'sex':'male'} # info_iter=info.__iter__() #---------執行__iter__()方法。獲得的是迭代器對象 # print(info_iter) #---------<dict_keyiterator object at 0x0000010BDC4110E8>字典的key值迭代器對象 # res1=info_iter.__next__() #---------迭代器對象執行__next__()方法,取出可迭代對象中的一個值 # print(res1) #---------name # res2=info_iter.__next__() # print(res2) #---------age # # res3=info_iter.__next__() # print(res3) #---------is_beautiful # # res4=info_iter.__next__() # print(res4) #---------sex # # info_iter.__next__() # 一旦迭代器取值取乾淨,再繼續取就會拋出StopIteration # info={'name':'egon','age':18,'is_beautiful':True,'sex':'male'} # # info=[1,2,3,4,5] # info_iter=info.__iter__() # while True: # try: # print(info_iter.__next__()) # except StopIteration: #判斷拋出的異常是否是StopIteration,是則執行break # break #for循環:迭代器循環 # info={'name':'egon','age':18,'is_beautiful':True,'sex':'male'} #in後跟的必定要是可迭代的對象 # for k in info: # info_iter=info.__iter__() # print(k) # f=open('a.txt','r') # for k in f: # print(k) #基於for循環,咱們能夠徹底再也不依賴索引去取值了 # dic={'a':1,'b':2,'c':3} # for k in dic: # print(dic[k]) #for循環的工做原理 #1:執行in後對象的dic.__iter__()方法,獲得一個迭代器對象iter_dic #2: 執行next(iter_dic),將獲得的值賦值給k,而後執行循環體代碼 #3: 重複過程2,直到捕捉到異常StopIteration,結束循環 # 總結: # 迭代器對象:指的是既內置有__iter__方法,又內置有__next__方法的對象 # 執行迭代器對象的__next__獲得的是迭代器的下一個值 # 執行迭代器對象的__iter__獲得的仍然是迭代器自己 # iter_info=info.__iter__() # # print(iter_info) # print(iter_info is iter_info.__iter__() is iter_info.__iter__().__iter__().__iter__().__iter__().__iter__()) #True # #總結迭代器對象的優缺點: #優勢: #一、提供了一種通用的、能夠不依賴索引的迭代取值方式 #二、迭代器對象更加節省內存 # f=open('movie.tar.gz','rb') # f.__ next__() # f=open('db.txt','rt',encoding='utf-8') # # print(f.__next__()) # print(f.__next__()) # print(next(f)) #f.__next__() # s='hello' # print(s.__len__()) # print(len(s)) # s.__iter__() # print(iter(s)) # 缺點: #一、迭代器的取值不如按照索引的方式更靈活,由於它只能日後取不能往前退 #二、沒法預測迭代器值的個數 # names=['egon','alex_SB','wxx_SB'] #取出列表中的第二個值,只能一個一個的取,也不能統計出列表的長度,只有取完再取的時候纔會拋出異常 # iter_names=iter(names) # print(next(iter_names)) # print(next(iter_names)) # # iter_names=iter(names) # print(next(iter_names)) # print(next(iter_names)) # # print(next(iter_names)) # # print(names[1]) #而使用索引則能夠很方面的就取出列表中的第二個值 # print(names[1]) # s=set('helllllo') #將字符串轉換成集合底層原理:就是先把字符串執行__iter__獲得迭代器對象,迭代器對象在執行__next__方法,將值取出來放到集合中,直到值被取乾淨 # print(s) # for i in 10: #10不可迭代對象,底層原理走不通因此會報錯,TypeError: 'int' object is not iterable # pass # list(10) #list底層原理也是for循環,因此放10也會包一樣的錯誤,TypeError: 'int' object is not iterable # names=['a','b','c','d'] # iter_names=iter(names) #names.__iter__()能夠改寫成iter(names)二者是等價的 # # l1=list(iter_names) #將迭代器對象循環放入獲得列表中 # print(l1) #['a', 'b', 'c', 'd'] # # l2=list(iter_names) #迭代器對象值已經所有放入到列表中,因此已經別取乾淨了,此時的列表爲空列表 # print(l2) #[] # f=open('db.txt','rt',encoding='utf-8') # # print(list(f)) #文件自己就是迭代器對象,因此第一次已經把文件中的值所有取乾淨了,['11111111111111111\n', '2222222222222\n', '33333\n', '4444\n', '55555'] # print(list(f)) #[] #迭代器對象已經爲空,因此獲得的列表也均爲空列表 # print(list(f)) #[] # print(list(f)) #[] # print(list(f)) #[] # l1=[1,2,3,] # diedaiqi=l1.__iter__() # print(list(l1)) #l1均爲迭代器對象,循環將值放入到列表中的列表都會有值,[1, 2, 3] # print(list(l1)) #[1, 2, 3] # print(list(l1)) #[1, 2, 3] # print(list(l1)) #[1, 2, 3] # print(list(l1)) #[1, 2, 3] # print(list(l1)) #[1, 2, 3]