函數名的使用: 函數名可以作為值,賦值給變數 函數名可以作為參數傳參給函數. 函數名可以作為返回值 函數名可以作為元素存儲在容器里 閉包:在嵌套函數內,使用外層局部變數(非全局變數)就是一個閉包,閉包可以多層嵌套.閉包的優點: 避免局部變數不被外界修改 函數生命周期延長 節省開闢空間,銷毀空間的時間 ...
函數名的使用:
- 函數名可以作為值,賦值給變數
- 函數名可以作為參數傳參給函數.
- 函數名可以作為返回值
- 函數名可以作為元素存儲在容器里
閉包:
在嵌套函數內,使用外層局部變數(非全局變數)就是一個閉包,閉包可以多層嵌套.
閉包的優點:
- 避免局部變數不被外界修改
- 函數生命周期延長
- 節省開闢空間,銷毀空間的時間
閉包的作用:就是使一個局部變數常駐記憶體,方便後面程式調用
如何查看一個函數是否是一個閉包
__closure__:查看一個函數是否是閉包
def func1(): str_ = "閉包" # 局部變數 def func2(): print(str_) # 使用局部變數,閉包 func2() print("fun2",func2.__closure__) # 列印func2是否是閉包 func1() print("fun1",func1.__closure__) #列印內容如下: 閉包 fun2 (<cell at 0x000000000222D7C8: str object at 0x000000000224E0E0>,) fun1 None
通過列印可以看出fun2是閉包,
閉包的調用:
def func1(): str_ = "閉包" # 局部變數 def func2(): print(str_) # 使用局部變數,閉包 print(func2.__closure__) # 列印func2是否是閉包 return func2 func1()() # 調用閉包func2() # 列印內容如下: (<cell at 0x00000000022ED7C8: str object at 0x0000000002431030>,) 閉包
迭代器:
iterable表示可迭代的對象.遵守可迭代協議 使用dir(對象)可以查看數據類型是否符合可迭代協議.dir(對象)可以獲取對象所有的方法,如果方法中有__iter__說明對象遵守可迭代協議,是可迭代類型數據.如下:
s = "Hello World" print(dir(s)) #列印內容如下: '__init_subclass__', '__iter__', '__le__', ' # 這裡只列印部分內容
還可以通過isinstance(對象,參數)來檢測是可迭代對象還是迭代器.如果返回結果為True是可迭代對象,如果False不是可迭代對象.下麵是對常見數據類型的列印:
num = 10 bool_t = True str_1 = "Hello World" list_1 = [1,2,3] tuple_1 = (1,2,3) dict_1 = {"電影":"黃飛鴻","電視劇":"上海灘"} set_1 = {1,2,3,4} from collections.abc import Iterable print("int:",isinstance(num,Iterable)) print("str:",isinstance(str_1,Iterable)) print("bool:",isinstance(bool_t,Iterable)) print("list:",isinstance(list_1,Iterable)) print("tuple:",isinstance(tuple_1,Iterable)) print("dict:",isinstance(dict_1,Iterable)) print("set:",isinstance(set_1,Iterable)) print("range:",isinstance(range(10),Iterable)) #列印結果如下 int: False str: True bool: False list: True tuple: True dict: True set: True range: True
由此可以得出,可迭代對象:有str,list,dict,set,tuple,range()
迭代器:如果可迭代對象中有__iter__函數就可以理解為是遵守可迭代協議的,那麼這個可迭代對象就可使用__iter__以創建一個迭代器對象.在迭代器中可以使用__next__方法來獲取所有迭代器中的元素.如下:
str_1 = "Hello World" from collections.abc import Iterable,Iterator print(isinstance(str_1,Iterator)) # 查看是否是迭代器 str_iter = str_1.__iter__() # 創建迭代器 print(isinstance(str_iter,Iterator)) # 查看是否是迭代器 #列印結果如下: False True
由此可以證明上面的結論,可迭代對象通過__iter__方法創建迭代器.
for迴圈的工作原理就是通過迭代器來實現的.
下麵來看個簡單的迭代器
str_1 = "Hello" str_iter = str_1.__iter__() print(str_iter.__next__()) print(str_iter.__next__()) print(str_iter.__next__()) print(str_iter.__next__()) print(str_iter.__next__()) #列印內容如下: H e l l o
由上面的輸出可以看出與for迴圈的輸出類似.並且迭代器是不可回退的.但是當我們的迭代器超過字元串的長度後會報錯StopIteration,那在使用for迴圈時for是怎麼知道對象的長度,並且不會報錯的呢?
下麵我們用while迴圈和迭代器模擬for迴圈的內部機制.
str_1 = "Hello" str_iter = str_1.__iter__() while True: try: # 捕獲異常 print(str_iter.__next__()) # 列印迭代器內容 except StopIteration: # 處理異常 break #列印內容如下: H e l l o
註意:迭代器只能向下執行是不能回退的.
總結:
Iterable: 可迭代對象. 內部包含__iter__()函數
Iterator: 迭代器. 內部包含__iter__() 同時包含__next__().
迭代器的特點:
- 節省記憶體.
- 惰性機制
- 不能反覆, 只能向下執行.