帶參裝飾器
一般,裝飾器爲被裝飾的函數添加新功能,須要外界的參數函數
-- outer參數固定一個,就是func對象
-- inner參數固定同被裝飾的函數,也不能添加新參數
-- 能夠藉助函數的嵌套定義,外層給內層傳參索引
def wrap(info):
def outer(func):
# info = 0
def inner(*args, **kwargs):
print('新:拓展的新功能,可能也須要外界的參數%s' % info)
res = func(*args, **kwargs)
return res
return inner
return outerit
@wrap('外部參數')io
def fn(): passfor循環
系統的wraps帶參裝飾器:改變inner的假指向,本質外界使用的仍是inner,可是打印顯示的是wraps中的函數import
from functools import wraps
def
outer(func):
@wraps(func)
def inner(*args, **kwargs):
容器
res = func(*args, **kwargs)
return res
return inner原理
@outer object
def fn(): pass
迭代對象
迭代器:循環反饋的容器(集合類型)
-- 不一樣於索引取值,但也能夠循環的從容器對象中從前日後逐個返回內部的值
優勢:不依賴索引,完成取值
缺點:不能計算長度,不能指定位取值(只能從前日後逐一取值)
可迭代對象
可迭代對象:有__iter__()方法的對象是可迭代對象,可迭代對象調用__iter__()獲得迭代器對象
ls = [4, 1, 5, 2, 3]
res = ls.__iter__() # => 可迭代對象
print(res) <list_iterator object at 0x000002732B0C7470>
迭代對象
迭代器對象:有__next__()方法的對象是迭代器對象,迭代器對象依賴__next__()方法進行取值
with open('1.txt', 'rb') as f:
res = f.__next__() # 文件中的第一行內容
print(res)
res = f.__next__() # 文件中的第二行內容
print(res)
for循環迭代器
直接用while True循環在迭代器對象中經過 __next__() 取值,取空時,取空再取值,報StopIteration異常
ls = [3, 1, 2, 3, 5]
iterator = ls.__iter__()
while True:
try:
print(iterator.__next__())
except StopIteration:
# print('取空了')
break
for循環就是對while取迭代器對象的封裝
for v in ls:
print(v)
for v in ls.__iter__(): #可迭代對象.__iter__() => 迭代器對象
print(v)
iterator = ls.__iter__()
for v in iterator: # 迭代器對象.__iter__() => 自身
print(v)
for循環迭代器的工做原理:
for v in obj: pass
#
1)獲取obj.__iter__()的結果,就是獲得要操做的 迭代器對象
2)迭代器對象經過__next__()方法進行取值,依次將當前循環的取值結果賦值給v
3)當取值拋異常,自動處理StopIteration異常結束取值循環
生成器
生成器:自定義的迭代器對象
-- 就是用函數語法來聲明生成器,用yield關鍵字取代return關鍵字來返回值,參數沒有多少變化
總結:有yield關鍵字的函數,函數名() 不是調用函數,而是生成獲得 生成器對象,生成器對象就是迭代器對象,能夠經過 __next__() 進行取值
執行流程:
def fn():
yield 1
yield 3
yield 5
obj = fn()
obj.__next__()
從開始往下執行,遇到第一個yield中止,拿到yield的返回值
obj.__next__()
從上一次中止的yield往下執行,在再遇到的yield時中止,拿到當前中止的yield的返回值
...
以此類推,直到沒法得到下一個yield,拋StopIteration異常
能夠直接被for循環遍歷
for v in fn():
print v
案例一:建立生成器,從其取值,依次獲得1! 2! 3! ...
def jiecheng():
ji = 1
count = 1
while True:
ji *= count
yield ji
count += 1
obj = jiecheng()
print(obj.__next__())
print(obj.__next__())
print(obj.__next__()) # 能夠無限取
案例二:
def jiecheng_num(num):
ji = 1
for i in range(1, num + 1):
ji *= i
yield ji
# ..。
obj = jiecheng_num(3)
print(obj.__next__())
print(obj.__next__())
print(obj.__next__())
print(obj.__next__()) # 有異常了
for v in jiecheng_num(5):
print(v) # 會自動處理異常中止
案例三:
def my_range(num): # => [0, 1, 2, ..., num - 1]
count = 0
while count < num:
yield count
count += 1
for v in my_range(10):
print(v, end=' ')
print(list(my_range(10)))