帶參裝飾器,迭代器,生成器,列舉物件

2022-05-15 16:15:51 字數 4976 閱讀 5468

'''

函式的巢狀定義:在函式內部定義另乙個函式

閉包:被巢狀的函式

-- 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__() #

檔案中的第一行內容

print

(res)

res = f.__next__() #

檔案中的第二行內容

print

(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:

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__() 進行取值

#執行流程:

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 用法 所有函式呼叫的引數都是第一次呼叫時保留的,而不是新...