python函数高级运用
生活随笔
收集整理的這篇文章主要介紹了
python函数高级运用
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、裝飾器
1.1 閉包函數用法
# 需求: # 執行一個函數前需要認證是否登錄,如果登錄則不需再登錄. # 只認證一次,后續操作無需認證 # 要求認證使用閉包函數用法 # 閉包函數 = 函數嵌套 + 命名空間作用域 + 函數對象 login_status = {'user':None,'status':None }def login(user:str,pwd:str):if user == 'jmz' and pwd =='123':return Trueelse:return False# 認證用戶是否登錄成功 def auth(func):def wrapper(*args,**kwargs):if login_status['user'] and login_status['status']:return func(*args,**kwargs)else:uname = input('username>>').strip()upwd = input('password>>').strip()res =login(uname,upwd)if res:return func(*args, **kwargs)else:print('認證失敗')return wrapperdef index():print('from index')index = auth(index)def cat():print('form cat')index() cat() 實現1.2 什么是裝飾器
# 什么是裝飾器# 1、裝飾即修飾,器指的就是工具# 2、裝飾器本身可以是任意可調用的對象# 3、被裝飾的對象也可以是任意可調用的對象1.3 為什么要使用裝飾器
# 為什么要使用裝飾器# 1、在不改變原有的調用方式,不改變原方法的前提下,如何實現對內容上的新增??# 例如:# 今天公司cto要求對一些方法添加文件的日志記錄(此時你是否需要對每一個方法添加日志的記錄?)# 第二天CTO 突然改變主意說 原來的方法添加日志記錄改為 mysql 記錄(此時你是否又要修改每一個方法的日志記錄??)# 我知道你此時此刻一定會想,我可以寫一個日志記錄方法,讓每一個方法內部調用這個方法(很不錯的想法)# 第三天 你的公司cto 告訴你,我的日志一定要記錄那些方法執行的開始和結束時間。(是不是有點懵X了?你該怎么辦??)1.4 怎么用裝飾器
# 是否是和上面的那個閉包函數很像呀(其實裝飾器就是閉包函數的一種運用)# 裝飾器語法糖:# 在被裝飾對象的正上方一行寫@裝飾器的名字# @auth ==> func = auth(func) login_status = {'user':None,'status':None }def login(user:str,pwd:str):if user == 'jmz' and pwd =='123':login_status['user']=userlogin_status['status']=Truereturn Trueelse:return False# 認證用戶是否登錄成功 def auth(func):def wrapper(*args,**kwargs):if login_status['user'] and login_status['status']:return func(*args,**kwargs)else:uname = input('username>>').strip()upwd = input('password>>').strip()res =login(uname,upwd)if res:return func(*args, **kwargs)else:print('認證失敗')return wrapper@auth def index():print('from index')@auth def cat():print('form cat')index() cat() 怎么使用裝飾器1.5 有參裝飾器
# 上面的裝飾器只是使用了固定的用戶jmz,登錄,而且沒有實現以哪種方式 驗證(文件方式,還是mysql方式)# 如果我需要暫時以文件的方式驗證,后期再改為使用mysql 方式驗證該如何使用??? (盡量減少代碼的修改)# 要求:# 1、驗證的方式是不固定的# 2、使用的裝飾器要兼顧至少兩種以上的驗證方式# 3、需要能夠隨時給方法添加驗證或撤銷驗證 login_status = {'user':None,'status':None }def login(user:str,pwd:str,type='file'):if type == 'file':# 假設這就是文件認證if user == 'jmz' and pwd == '123':login_status['user'] = userlogin_status['status'] = Truereturn Trueelse:return Falseelif type =='mysql':# 假設這就是mysql認證if user == 'jmz' and pwd == '123':login_status['user'] = userlogin_status['status'] = Truereturn Trueelse:return False# 認證用戶是否登錄成功 def auth(type='file'):def auth2(func):def wrapper(*args,**kwargs):if login_status['user'] and login_status['status']:return func(*args,**kwargs)else:uname = input('username>>').strip()upwd = input('password>>').strip()res =login(uname,upwd,type)if res:return func(*args, **kwargs)else:print('認證失敗')return wrapperreturn auth2@auth('file') def index():print('from index')@auth('file') def cat():print('form cat')index() cat() 有參裝飾器?
二、迭代器
2.1 什么是迭代器?
迭代的工具:
迭代是一個重復的過程,每一次的重復都是基于上一次的結果進行的
# 這不是迭代 while True:print('....')2.2 為什么要使用迭代器?
找到一種不依賴于索引的迭代的方式?
# 1、列表是自帶索引的,那么如何迭代沒有索引的呢???(禁止使用for) l = ['a','b','c'] k = 0 while k<len(l):print(l[k])k+=1# 2、如何循環取一個無限大的值? # 如果使用上面的方法顯然是不現實的,因為你的列表是存不下無限大的值的(列表的數據占著內存的空間)# 那怎么辦呢?2.3 怎么使用迭代器?
2.3.1 可迭代對象
python 中,但凡內置__iter__方法的,都是可迭代對象
a = 1 b = 1.1 # 以下都是可以使用__iter__ 方法 c = 'abcd' #c.__iter__() d = ['a','b','c'] # d.__iter__() e = ('a','b','c') # e.__iter__() f = {'a':1,'b':2} # f.__iter__() g={'a','b','c'} # g.__iter__() h=open('a.txt','r') # 本身就是一個迭代器對象2.3.2 迭代器對象
# 可迭代對象:在python中但凡有內置方法__iter__的對象,都是可迭代對象 # 迭代器對象 : # 執行可迭代對象下__iter__方法后得到迭代器對象 # 迭代器對象的內置方法 # __next__ # __iter__方法,執行該方法得到仍然是迭代器本身,干什么用??(等下解釋)# 有了迭代器我們就不需要依賴索引取值了
# 注意:
# 1、迭代器對象一定是對迭代對象
# 2、可迭代對象不一定是迭代器對象 ? dic = {'a':1,'b':2,'c':3,'d':4} iter_obj = dic.__iter__() print(next(iter_obj)) # a print(next(iter_obj)) # b iter_obj1 = dic.__iter__() # 重新 做了一次迭代器對象操作 print(next(iter_obj1)) # a。 iter_obj = iter_obj.__iter__() # iter_obj.__iter__() is iter_obj #True #iter_obj.__iter__() 無論執行多少次都是本身 print(next(iter_obj)) # c # 會繼續給予上一次的操作繼續執行 print(next(iter_obj)) # d __iter__ ,迭代器對象執行后任然是本身 #for循環的底層運行機制:for循環可以稱之為迭代器循環 #1、先調用in后那個對象的__iter__方法,得到該對象的迭代器對象 #2、執行迭代器對象的__next__方法,將得到的返回值賦值in前面的變量名,然后執行一次循環體代碼 #3、循環往復,直到取干凈迭代器內所有的值,自動捕捉異常結束循環 dic = {'a':1,'b':2}iter_obj = dic.__iter__() while True:try :print(dic[iter_obj.__next__()])except StopIteration:breakfor k in dic: #iter_obj=dic.__iter__()print(dic[k]) for 循環實現原理
2.4 總結
# 優點: # 1、不依賴于索引的迭代取值 # 2、節省內存,計算取值# 缺點: # 1、無法獲取長度 # 2、只能next,不能向上取值,只能想下直至結束 迭代器的優缺點?
三、生成器
3.1 什么是生成器
# 函數內部含有yield關鍵字,那么該函數() 即為生成器。 # 自定義迭代器def func():print('first')yield 1print('second')yield 2print('third')yield 3f = func() print(f) #<generator object func at 0x0000000001DF0DB0>3.2 生成器的使用方式
# yield 返回值操作 # 生成器就是迭代器,所以用法與迭代器一樣# 仿range函數 def range(start:int,end:int,step=1):while start < end:yield start # 當一次next 執行到這里時便會返回start,并停止,下一次操作會從本次停止的地方繼續往下執行,start += step # 直到再次遇到 yield 再停止,返回后面的值 num = range(1,6,2) print(num.__next__()) print(num.__next__()) print(num.__next__())# yield : 具有停止本次操作,并return yield 后面的值,與return的返回值一樣 生成器使用方式一 # yield 傳值操作 def doing(name):print('%s開始干活了'%name)thing_list = set()while True:do_thing = yield thing_list # 返回thing_listprint('%s 正在%s'%(name,do_thing))thing_list.add(do_thing)xiaoming = doing('xiaoming') next(xiaoming) # 第一次使用,需暫停到yield 那邊 print(xiaoming.send('做飯')) # 先給yield 傳值, 之后再接受執行到下一個yield的返回值 print(xiaoming.send('吃飯')) print(xiaoming.send('干活')) print(xiaoming.send('睡覺')) xiaoming.close() # 關閉生成器 xiaoming.send('起床時') # 此時無法再傳值執行,并且報錯 生成器使用方式二3.3 總結
# 1、可以像return 一樣,返回值,但又可以多次返回 # 2、可以掛起/保存函數的當前狀態,可以達到隨用隨啟動的程度 # 3、可以多次傳值操作?
四、練習
# 作業一:寫一個取基數的操作 (迭代器) # 作業二:咖啡3元,糖0.5元 牛奶2元,平時咖啡單點的,活動需要,需加糖與牛奶捆綁銷售(裝飾器) # 作業三:用戶購買商品,以郵箱或短信的形式通知(裝飾器) #作業一 def jishu():num = 1while True:is_true = Trueif num > 1:count = 2while count < num - 1:if num%count==0:is_true = Falsebreakcount +=1if is_true:yield numnum +=1num = jishu() print(next(num)) print(next(num)) print(next(num)) print(next(num)) print(next(num))#作業二 def sugar(func):def wrapper(*args,**kwargs):res = func(*args,**kwargs)res += 0.5return resreturn wrapperdef milk(func):def wrapper(*args,**kwargs):res = func(*args,**kwargs)res += 2.5return resreturn wrapper@sugar @milk def coffee():return 3print(coffee())#作業三 def notice(type='email'):def shopping(func):def wrapper(*args,**kwargs):if type == 'email':print('郵箱通知成功')elif type == 'sms':print('短信通知成功')return func(*args,**kwargs)return wrapperreturn shopping@notice('sms') def shopping(good):print('成功購買了%s商品'%good)shopping('電腦') 作業?
轉載于:https://www.cnblogs.com/xiaobaiskill/p/8998714.html
總結
以上是生活随笔為你收集整理的python函数高级运用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: EBS常用表_Dictionary
- 下一篇: 关于JS阶乘,首字母大写,最长单词计算,