網站首頁 編程語言 正文
python 迭代器與生成器,裝飾器
迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結束。
迭代器有兩個基本的方法:iter() 和 next()。
字符串,列表或元組對象都可用于創建迭代器:
list1=[1,2,3] s=iter(list1) # 創建迭代器對象 print(next(s)) # 輸出迭代器的下一個元素 print(next(s)) print(next(s))
直到計算出最后一個元素,沒有更多的元素時,拋出StopIteration的錯誤
迭代器對象可以使用常規for語句進行遍歷:
list2=[1,2,3,4,5] s2 = iter(list2) # 創建迭代器對象 for h in s2: print (h, end="-")
生成器
帶有 yield 的函數在 Python 中被稱之為 generator(生成器)(自己制作迭代器可以看做是生成器)
#注意括號 #列表生成式 lis = [x+x for x in range(5)] print(lis) #生成器 gen= (x+x for x in range(5)) print(gen) # gen = (x+x for x in range(5)) # print(next(gen)) # print(next(gen)) # print(next(gen)) # print(next(gen)) # print(next(gen)) generator_ex = (x+x for x in range(5)) for i in generator_ex: print(i)
自己產生一個支持小數的range生成器(即帶yield的迭代器)
你先把yield看做“return”,這個是直觀的,它首先是個return,普通的return是什么意思,就是在程序中返回某個值,返回之后程序就不再往下運行了。看做return之后再把它看做一個是生成器(generator)的一部分(帶yield的函數才是真正的迭代器),
def frange(star,stop,step): x=star while x<stop: yield x x+=step for i in frange(10,20,0.5): print(i)
下圖最直觀得可以看出yield的作用
把yield想想成return,return了一個4之后,程序停止,并沒有執行賦值給res操作。
一個帶有 yield 的函數就是一個 generator,生成一個 generator 看起來像函數調用,但不會執行任何函數代碼,直到對其調用 next()(在 for 循環中會自動調用 next())才開始執行。雖然執行流程仍按函數的流程執行,但每執行到一個 yield 語句就會中斷,并返回一個迭代值,下次執行時從 yield 的下一個語句繼續執行。看起來就好像一個函數在正常執行的過程中被 yield 中斷了數次,每次中斷都會通過 yield 返回當前的迭代值。
def foo(): print("starting...") while True: print("yield前") res = yield 4 print("yield后") print("res:", res) g = foo() print(next(g)) print("*" * 20) print(next(g))
在我們調用這個函數的時候,第一件事并不是執行這個函數,而是將這個函數做為參數傳入它頭頂上這頂帽子,這頂帽子我們稱之為裝飾函數 或 裝飾器。
裝飾器的使用方法很固定:
先定義一個裝飾函數(帽子)(也可以用類、偏函數實現)
再定義你的業務函數、或者類(人)
最后把這頂帽子帶在這個人頭上
裝飾器的簡單的用法有很多,這里舉兩個常見的。
日志打印器
時間計時器
# 這是裝飾函數 def logger(func): def wrapper(*args, **kw): print('我準備開始計算:{} 函數了:'.format(func.__name__)) # 真正執行的是這行。 func(*args, **kw) print('啊哈,我計算完啦。給自己加個雞腿!!') return wrapper @logger def add(x, y): print('{} + {} = {}'.format(x, y, x+y)) add(200, 50)
# 這是裝飾函數 def timer(func): def wrapper(*args, **kw): t1=time.time() # 這是函數真正執行的地方 func(*args, **kw) t2=time.time() # 計算下時長 cost_time = t2-t1 print("花費時間:{}秒".format(cost_time)) return wrapper import time @timer def want_sleep(sleep_time): time.sleep(sleep_time) want_sleep(10)
def american(): print("我來自中國。") def chinese(): print("I am from America.") def say_hello(contry): def wrapper(func): def deco(*args, **kwargs): if contry == "china": print("你好!") elif contry == "america": print('hello.') else: return # 真正執行函數的地方 func(*args, **kwargs) return deco return wrapper @say_hello("china") def american(): print("我來自中國。") @say_hello("america") def chinese(): print("I am from America.")
總結
原文鏈接:https://blog.csdn.net/weixin_44740756/article/details/122844911
相關推薦
- 2022-08-15 springboot的熱部署配置
- 2022-02-21 windows11安裝docker desktop
- 2022-06-27 ASP.NET?MVC開發接入微信公共平臺_實用技巧
- 2022-06-07 Python必備技巧之函數的使用詳解_python
- 2023-11-17 在python中按不同的條件在列表list、字典dict和集合set中篩選想要的數據(以實際案例進行
- 2023-11-23 python的相對路徑表示方式
- 2023-10-26 void 0 有什么意義?undefined竟然是可變的?
- 2022-08-13 Redis - 數據結構和持久化機制
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支