python記錄_day11 閉包 迭代器
一、第一類物件:
函式名是一個變數,可以當普通變數使用,但它又是一個特殊的變數,與括號配合可以執行函式。
函式名的運用
1、單獨列印是一個記憶體地址
2、可以給其他變數賦值
3、可以作為容器類變數的元素
4、可以作為函式的引數
5、可以作為函式的返回值
二、閉包
如果一個內層函式有對外層函式變數的引用,那麼就稱為這個內層函式為閉包函式,也叫閉包
那麼,如何檢查一個函式是不是閉包函式呢?
用__closure__()方法可以檢查函式是否是閉包函式,返回值不為None就是閉包函式。
def func(): name = "alex" def func2():print(name) func2() print(func2.__closure__) #(<cell at 0x00000000027375B8: str object at 0x00000000027B81B8>,) func() print(func.__closure__) #None
閉包的作用
1、保護變數不受侵害。閉包函式引用的是區域性變數,因此變數不容易被修改
2、可以讓一個變數常駐記憶體。因為內層函式執行的時機是不確定的,為了inner函式能正常執行,必須保證變數存在。
如何訪問內部函式?
訪問內部函式,可以先呼叫外部函式,獲取內部函式地址,再呼叫內部函式即可。多層巢狀就一層一層的返回
def outer(): name = "alex" #內部函式 def inner(): print(name) return inner fn = outer() #呼叫外部函式 獲取內部函式的函式地址 fn() #呼叫內部函式
兩個方法:
__doc__() 檢視函式的文件註釋
__name__() 檢視函式名
三、迭代器
迭代器就是個可以使用__next__函式一個一個往外拿值的容器。比如 a是一個迭代器,那麼a.__next__()就表示從a中拿出了一個值。
dir() 能夠檢視資料型別能夠執行的操作,即該資料型別支援的內部方法
print(dir(list)) #結果 ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__',
'__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__',
'__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__',
'__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop',
'remove', 'reverse', 'sort']
通過對list、set、tuple、str等資料型別檢視,我們都能發現一個__inter__函式,這是可迭代物件的共性。其實__inter__函式相當於是一個可迭代協議,只要有這個函式,就表示它是可迭代的。__inter__函式的作用是獲取物件的迭代器。
因此
一個物件有__inter__函式,表示可迭代的(iterable)
有__iter__, __next__函式,表示是迭代器(iterator),迭代器都是可迭代的
如何判斷一個物件是否是可迭代物件?
1、dir(x) 檢視是否具有__iter__函式
2、“__iter__” in dir(x) 判斷是否可迭代 返回值是True 或False
"__next__" in dir(x) 判斷是否是迭代器 返回值是True 或False
3、專業方法
from collections import Iterable,Iterator
isinstance(x ,Iterable) 表示 x是否是Iterable
isinstance(x,Iterator) 表示x 是否是Iterator
迭代器的三個特點:
1、節省記憶體
2、惰性機制 必須通過__next__()才能拿值
3、只能往前,不能後退
使用while+迭代器模擬for迴圈:
lst = [1,2,3]
it = lst.__iter__() #得到迭代器
while 1:
try:
el = it.__next__()
for迴圈的迴圈體
except StopIteration:
break
lst = [1,2,3] it = lst.__iter__() while 1: try: el = it.__next__() print(el) except StopIteration: break #等價於 for el in lst: print(el)