'''函式的巢狀定義:在函式內部定義另乙個函式
閉包:被巢狀的函式
-- 1.外層通過形參給內層函式傳參
-- 2.驗證執行
開放封閉原則: 功能可以拓展,但源**與呼叫方式都不可以改變
裝飾器:裝飾器名就是外層函式 @outer
@outer # fn = outer(fn)
def fn(): pass
'''def
wrap(func):
def inner(*args, **kwagrs):
#res = func(*args, **kwagrs)
res =outer.inner()
return
res
return
inner
defouter(func):
def inner(*args, **kwagrs):
pass
res = func(*args, **kwagrs)
pass
#res
return
res
return
inner
@wrap
#fn = warp(fn) = wrap(outer.inner) = wrap.inner
@outer #
fn = outer(fn) = outer.inner
def fn(n1, n2, n3): pass
fn(1, 2, 3)
#1.帶參裝飾器 | wraps(文件注釋) 了了解
#2.迭代器 *****
#可迭代物件
#迭代器物件
#for迭代器
#列舉物件
#遞迴 ***
#通常,裝飾器為被裝飾的函式新增新功能,需要外界的引數
#-- outer引數固定乙個,就是func
#-- inner引數固定同被裝飾的函式,也不能新增新引數
#-- 可以借助函式的巢狀定義,外層給內層傳參
defwrap(info):
defouter(func):
#info = 0
def inner(*args, **kwargs):
print('
新:拓展的新功能,可能也需要外界的引數%s
' %info)
res = func(*args, **kwargs)
return
res
return
inner
return
outer
@wrap(
'外部引數')
def fn(): pass
#系統的wraps帶參裝飾器:改變inner的假指向,本質外界使用的還是inner,但是列印顯示的是wraps中的函式
from functools import
wraps
defouter(func):
@wraps(func)
def inner(*args, **kwargs):
res = func(*args, **kwargs)
return
res
return
inner
@outer
def fn(): pass
#迭代器物件: 可以不用依賴索引取值的容器
#可迭代物件:可以通過某種方法得到迭代器物件
#迭代器優點:可以不用依賴索引取值
#迭代器缺點:只能從前往後依次取值
#可迭代物件:有__iter__()方法的物件是可迭代物件,可迭代物件呼叫__iter__()得到迭代器物件
ls = [4, 1, 5, 2, 3]
res = ls.__iter__()
#=> 可迭代物件
print(res) #
#可迭代物件有哪些:str | list | tuple | set | dict | range() | enumerate() | file | 生成器物件
#迭代器物件:有__next__()方法的物件是迭代器物件,迭代器物件依賴__next__()方法進行取值
with open(
'1.txt
', 'rb'
) as f:
res = f.__next__() #
檔案中的第一行內容
(res)
res = f.__next__() #
檔案中的第二行內容
(res)
#迭代器物件有哪些:enumerate() | file | 生成器物件
#注:迭代器物件呼叫__iter__()方法返回的還是迭代器物件(返回自身)
#直接用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:
(v)
for v in ls.__iter__(): #
可迭代物件.__iter__() => 迭代器物件
(v)
iterator = ls.__iter__
()
for v in iterator: #
迭代器物件.__iter__() => 自身
(v)
#
for迴圈迭代器的工作原理:#
for v in obj: pass
#1)獲取obj.__iter__()的結果,就是得到要操作的 迭代器物件
#2)迭代器物件通過__next__()方法進行取值,依次將當前迴圈的取值結果賦值給v
#3)當取值拋異常,自動處理stopiteration異常結束取值迴圈
#生成器:自定義的迭代器物件
#-- 就是用函式語法來宣告生成器,用yield關鍵字取代return關鍵字來返回值,引數沒有多少變化
#總結:有yield關鍵字的函式,函式名() 不是呼叫函式,而是生成得到 生成器物件,生成器物件就是迭代器物件,可以通過 __next__() 進行取值
#執行流程:
deffn():
yield 1
yield 3
yield 5obj =fn()
obj.
__next__() #
從開始往下執行,遇到第乙個yield停止,拿到yield的返回值
obj.__next__() #
從上一次停止的yield往下執行,在再遇到的yield時停止,拿到當前停止的yield的返回值
#... # 以此類推,直到無法獲得下乙個yield,拋stopiteration異常
#可以直接被for迴圈遍歷
for v in
fn():
print v
#案例一:建立生成器,從其取值,依次得到1! 2! 3! ...
defjiecheng():
ji = 1count = 1
while
true:
ji *=count
yield
ji count += 1obj =jiecheng()
print(obj.__next__
())print(obj.__next__
())print(obj.__next__()) #
可以無限取
#案例二:
defjiecheng_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 yield
count
count += 1
for v in my_range(10):
print(v, end='')
print(list(my_range(10)))
#給可迭代器物件及迭代器物件新增迭代索引
s = '
abc'
for v in
enumerate(s):
print(v) #
(0 'a') | (1 'b') | (2 'c')
帶參裝飾器,迭代器與生成器
帶參裝飾器 通常,裝飾器為被裝飾的函式新增新功能,需要外界的引數 outer引數固定乙個,就是func inner引數固定同被 裝飾的函式,也不能新增新功能 可以借助函式的巢狀定義,外層給內層傳參 def wrap info def outer func info 0 def inner args,...
裝飾器,生成器,迭代器
裝飾器 import time def show time func def inner x start time time.time func x end time time.time print end time start time return inner show time def add...
迭代器 生成器 裝飾器
1.迭代器 1 定義 同時滿足 iter 方法和next 方法的物件就是迭代器。3 型別 可迭代物件通過iter 轉為迭代器 生成器是一種特殊的迭代器。2.生成器 1 定義 生成器是迭代器的一種,包括含有yield關鍵字函式和生成器表示式。2 用法 所有函式呼叫的引數都是第一次呼叫時保留的,而不是新...