過了元旦,加油鴨,衝鴨!!!閉包
閒話不說,開始今日份學習整理。函數
今日目錄,今天的學習內容不是不少!學習
1.函數名的運用spa
2.閉包(重要)code
3.迭代器(重要)對象
開始今日份總結blog
1.函數名的運用內存
1.1函數名是一個特殊的變量utf-8
def func(): print(666) print(func) #結果 <function func at 0x000001C2D44E7F28> #返回函數的內存地址
1.2函數名能夠當作變量賦值it
def func(): print(666) func2 = func f1 = func2 f2 = f1 f3 = f2 print(f3) #結果,返回函數的內存空間 <function func at 0x0000020FA58B7F28>
1.3函數名能夠當作容器類數據類型的元素
def func1(): print('func1') def func2(): print('func2') def func3(): print('func3') li =[func1,func2,func3] for i in li: i() #這樣就能夠一個一個的去調用函數了
1.4函數名能夠當作函數的參數
def func(x): x() print('in func') def func1(): print('in func1') func(func1) #結果 in func1 in func
1.5函數名能夠當作函數的返回值
def func(x): # x ---> func1 return x # func1 def func1(): print('in func1') ret = func(func1) # func1 ret() #結果 in func1
2.閉包(重要)
定義:
閉包的肯定
#不是閉包 name = 'test' def func1(): def inner(): print(name) return inner() f = func1() print(f.__closure__[0].cell_contents) #結果 AttributeError: 'NoneType' object has no attribute '__closure__' #表示函數內沒有閉包的參數 #是閉包 # 閉包 def func(): age =18 name ='test' def inner(): print(age) print(name) return inner f = func() # 獲取閉包引用的外層變量 print(f.__closure__[0].cell_contents) print(f.__closure__[1].cell_contents) #結果 18 test
閉包的用法
需求,輸入一個數,連續自加這個數五次,有可能會寫成這樣
def func(step): sum = 1 sum += step print(sum) i =0 while i <5: func(3) i+=1 #結果 4 4 4 4 4
閉包:解釋器執行程序時,若是遇到函數,隨着函數的結束而關閉臨時名稱空間,可是!!!
若是遇到閉包,有一個機制:那麼閉包的空間不會隨着函數的結束而關閉。
從新寫一下上面這個需求
def func(step): sum1 = 1 def inner(): nonlocal sum1 sum1 += step print(sum1) return inner i =0 f =func(3) while i <5: f() i+=1 #結果 4 7 10 13 16
須要注意的是,若是將f =func(3)放入下面循環內部,就會發現打印的都是4,緣由呢,就是生產了五個閉包,每一個閉包執行了一次。
閉包的經常使用使用環境
3.迭代器(重要)
3.1可迭代對象
經常使用可迭代對象爲:str list tuple set range() 文件句柄
可迭代對象:內部含有__iter__方法的就是可迭代對象,遵循可迭代協議,可迭代對象不能直接取值
判斷是不是可迭代對象
# 方法一:
s1 = 'barry'
# print('__iter__' in dir(s1))
# print('__iter__' in dir(range(10)))
3.2迭代器
迭代器:內部含有'__iter__'而且含有'__next__'方法的就是迭代器,遵循迭代器協議。
可迭代對象轉化成迭代器
可迭代對象.__iter__() 或者 iter(可迭代對象)
s1 = 'abcd' obj = iter(s1) print(obj) print(obj.__next__()) print(obj.__next__()) print(obj.__next__()) print(obj.__next__()) print(obj.__next__()) # 一個next 對應一個值,一一對應。 #結果 a b c d print(obj.__next__()) StopIteration
判斷
一個對象是是迭代器
#方法一:判斷一個對象內有沒有指定的方法 li =[1,2,3,4] obj = iter(li) print('__iter__'in dir(obj) and '__next__'in dir(obj)) #結果 True #方法二:引入其餘模塊,進行判斷 from collections import Iterable from collections import Iterator li =[1,2,3,4] obj = iter(li) print(isinstance(obj,Iterable))#判斷是不是可迭代對象 print(isinstance(obj,Iterator))#判斷是不是迭代器 #結果 True True #這個也能夠用於判斷上面是不是可迭代對象
type() isinstance()區別?
type()只是判斷該對象的數據類型
isinstance()不只能夠判斷該對象的數據類型,並且能夠判斷其餘不少
迭代器的做用:
1,節省內存.
2,惰性機制.
3, 一條路走到黑,不走回頭路.
s2 = [1, 2, 3, 4, 5]
obj2 = iter(s2)
print(next(obj2))
print(next(obj2))
練習
# 練習 # 判斷一個對象是不是可迭代對象,迭代器 # str list tuple set dict range() 文件句柄 # f = open('file',encoding='utf-8',mode='w') # print(isinstance(f,Iterator)) # s2 = [1, 2, 3] # # 將s2轉化成迭代器 進行取值 # obj2 = iter(s2) # # print(obj2.__next__()) # print(next(obj2)) #while循環模擬for循環機制