1. 程式人生 > 實用技巧 >python基礎知識--9迭代器生成器閉包與裝飾器

python基礎知識--9迭代器生成器閉包與裝飾器

1.迭代器


for i in range(1,10):
print(i,end=' ')

執行結果:

1 2 3 4 5 6 7 8 9

本章之前的程式碼,使用過for迴圈語句的,本質上都是迭代器的應用;
迭代器,可以理解為一個容器,迴圈的時候,每次從容器中取出一個數據,直到資料被取完為止。

如何自定義一個迭代器
以類為例:
需要在類中,實現兩個方法 __iter__ 與 __next__

其中:
1. __iter__ 方法需要返回物件本身,它是for迴圈使用迭代器的要求;
2. __next__ 方法用於返回容器中下一個元素,當容器中的資料取完時,需要引發 StopIteration異常。



# 需求:
# 1.自定義迭代器,通過傳入最小值最大值,返回該範圍所有數值的3次方
# 2.將返回的值,存入num_list 列表中

#%%

class Number():
def __init__(self,min,max):
self.min = min
self.max = max
def __iter__(self):
return self
def __next__(self):
# 返回這個範圍內所有數值的3次方
num = self.min

if self.min <= self.max:
self.min +=1
return num **3
else:
raise StopIteration

for i in Number(1,10):
print(i,end =' ')
執行結果:
1 8 27 64 125 216 343 512 729 1000 

num_list = []
for i in Number(1,5):
num_list.append(i)

num_list
執行結果:
[1, 8, 27, 64, 125]
2.生成器如果一個列表中,存有海量的資料,如果僅僅只是想訪問其中某幾個元素,那麼這樣的操作會特別耗記憶體;

生成器特點:
1.操作海量資料,節約大量記憶體空間。

生成器建立:
函式中如果包含yield關鍵字,那麼這個函式就不再是一個普通函式,而是一個生成器(generator)物件。
在 Python 中,使用了 yield 的函式被稱為生成器(generator)。

執行特點:
1.跟普通函式不同的是,生成器是一個返回迭代器的函式,只能用於迭代操作,更簡單點理解生成器就是一個迭代器。
2.在呼叫生成器執行的過程中,每次遇到 yield 時函式會暫停並儲存當前所有的執行資訊,返回 yield 的值,
並在下一次執行 next() 方法時從當前位置繼續執行。


# 建立一個生成器,傳入最大最小值,執行 next()方法。

def mygene(min,max):
while min < max:
yield min
min +=1


my_gene = mygene(1,5)

next(my_gene)
執行結果:1

next(my_gene)
執行結果:2

next(my_gene)
執行結果:3


# yield 與 return 區別
# return後,會跳出當前函式。yield 不會跳出當前函式。
# yield儲存當前函式的執行狀態,在返回後,函式又回到之前儲存的狀態繼續執行。

#%%

def test():
return 1
return 2

def genetest():
yield 1
yield 2


test = genetest()


next(test)
執行結果:1

next(test)
執行結果:2

3.閉包

# 閉包特點:
# 1.函式內部,再定義函式;
# 2.內部函式引用了外部變數但非全域性變數;
# 3.需要把內部函式返回。

#%%

def outer():
a = 0
def inner(b):
print(a+b)
return inner

f = outer()

f.__closure__[0].cell_contents
執行結果:0


# 疑問:
# 如何修改閉包函式變數a的值

#%%

def outer():
a = 0
def inner(b):
print(a+b)
return inner

def outer():
a = 0
def inner(b):
nonlocal a
a +=b
return inner

f = outer()

f(30)

f.__closure__[0].cell_contents

執行結果:40

# 閉包作用
# 1.定製裝飾器
# 2.並行運算
# ....
4.裝飾器
def func():
print('hello func')

def func1():
print('hello func1')

# 需求:
# 給上面函式,加上兩句列印
# print('開始執行')
# print('結束執行')

def func():
print('開始執行')
print('hello func')
print('結束執行')


裝飾器


裝飾器是一種增加函式或類功能的簡單方法,它可以快速地給不同的函式或類傳入相同的功能。
呼叫被裝飾的函式,與之前的呼叫過程沒有任何的區別

# 基本格式

def decorate(func): # 定義裝飾器函式,引數為func,代表被裝飾的函式
def wrapper(*args,**kwargs): # 新定義一個包裝函式,用於返回

func(*args,**kwargs) # 呼叫被裝飾的函式

return wrapper # 返回包裝函式


def decorate(func):
def wrapper(*args,**kwargs):
print('執行開始')
func(*args,**kwargs)
print('執行結束')
return wrapper

@decorate
def func():
print('hello func')

func()
執行結果:

執行開始 hello func 執行結束

@decorate
def func1():
print('hello func1')

func1()
執行結果:
執行開始
hello func1
執行結束