一.今日主要內容總覽(重點)緩存
1.第一類對象->函數名=>變量名
(1)函數對象能夠像變量同樣進行賦值
(2)還能夠做爲列表的元素進行使用
(3)還能夠做爲返回值返回
(4)還能夠做爲參數進行傳遞
思想:函數名就是變量名
(不只指向一塊空間,還有自身的意義)
2.閉包->函數的嵌套
(1)內層函數對外層函數中的變量的使用
(2)好處:
1.保護變量不被侵害
2.讓一個變量常駐內存
(3)如何經過代碼查看一個閉包?
__closure__: 有東西就是閉包,沒東西就不是閉包
(4)迭代器=>固定的思路.for循環
一個數據類型中包含了__iter__函數表示這個數據是可迭代的
dir(數據):返回這個數據能夠執行的全部操做
(5) 判斷迭代器和可迭代對象的方案(野路子)
__iter__ 可迭代的
__iter__ __next__ 迭代器
(6)判斷迭代器和可迭代對象的方案(官方)
from collections import Iterable, Iterator
isinstance(對象, Iterable) 是不是可迭代的
isinstance(對象, Iterator) 是不是迭代器
(7)模擬for循環
lst=[]
#拿迭代器
it=lst.__iter__()
while 1:
try:
it.__next__()
excep StopIteration:
break
#特徵:
爲了保證安全,咱們在內部調用
1. 省內存(生成器)
2. 惰性機制
3. 只能向前. 不能後退
做用:統一了各類數據類型的遍歷
3.迭代器->固定的思路.for循環
for循環的底層意義
二.今日內容大綱安全
1.第一類對象網絡
2.閉包閉包
3.迭代器app
三.內容詳解函數
1.第一類對象網站
(1)url
def fn(): print('我叫fn') print(fn)#結果:<function fn at 0x0000025672D298C8>
(2)spa
def fn(): print('我叫fn') fn() print(fn) gn=fn #函數名能夠進行賦值操做 print(gn) gn() ''' 結果: <function fn at 0x00000185567798C8> <function fn at 0x00000185567798C8> '''
(3).net
def func1(): print('朱元璋') def func2(): print('朱祁鎮') def func3(): print('徐潔') def func4(): print('魏忠賢') #操做一 lst=[func1,func2,func3,func4]#列表中什麼均可以放,沒有數據類型的限制 print(lst) #結果:朱元璋 #操做二: lst[0]() #操做三: for el in lst: #el是列表中的每一項. el() #拿到函數,執行函數 ''' 結果: 朱元璋 朱祁鎮 徐潔 魏忠賢 '''
(4)
def func1(): print('朱元璋') def func2(): print('朱祁鎮') def func3(): print('徐階') def func4(): print('魏忠賢') #操做一 lst=[func1(),func2(),func3(),func4()] print(lst) ''' 結果:#總結:先調用每個,由於沒有返回值,只能是4個None 朱元璋 朱祁鎮 徐潔 魏忠賢 [None, None, None, None] '''
(5)
a=10 b=20 c=30 lst=[a,b,c] print(lst) ''' 結果: [10, 20, 30]
(6)
a=10 b=20 c=30 lst=[a,b,c] print(lst) ''' 結果: [10, 20, 30] ''' #經過(4)和(5),發現變量和函數的操做是同樣的,變量可能數據類型不一樣 #函數數據類型相同,變量的每次數據類型不必定相同
(6)#重點降臨
def wrapper(): def inner(): print('個人天,還能夠這樣?') print(inner) #<function wrapper.<locals>.inner at 0x0000021F4F929950> # inner() return inner ret=wrapper() print(ret) #<function wrapper.<locals>.inner at 0x0000021F4F929950>
(6-1)
def wrapper(): def inner(): print('個人天,還能夠這樣?') print(inner) #<function wrapper.<locals>.inner at 0x0000021F4F929950> # inner() return inner ret=wrapper() print(ret) ##<function wrapper.<locals>.inner at 0x0000021F4F929950> ret() #個人天,還能夠這樣?
#總結:在函數外部訪問了函數內部的函數
''' 結果: <function wrapper.<locals>.inner at 0x000001F1B8609950> <function wrapper.<locals>.inner at 0x000001F1B8609950> 個人天,還能夠這樣? '''
(7)
def wrapper(): def inner(): print('大冬瓜') return inner #函數名能夠向返回值同樣返回#返回的是inner,也就是ret ret=wrapper() ret() #在函數外面訪問了函數內部的函數 ret() ret()
結果:
大冬瓜
大冬瓜
大冬瓜
(8)
def func1(): print('謝晉') def func2(): print('楊士奇') def func3(): print('徐渭') def func4(): print('柳如是') #代理函數 #代理,也是裝飾器的雛形 def proxy(a): #a就是變量,形參 #函數做爲參數進行傳遞 #代理好處,能夠加點東西 print('我是代理') a() print('代理執行完畢') proxy(func1) proxy(func3) proxy(func4)
總結:函數名就是變量名
1.函數名能夠像變量同樣進行傳遞
2.函數名能夠做爲參數進行賦值操做
3.能夠做爲返回值返回
4.能夠做爲參數進行傳遞
2.閉包
(1)
def wrapper(): name='周杰倫' def inner(): print(name)#在內層函數中,使用了外層函數的局部變量 inner() wrapper() ''' 結果: 周杰倫 '''
(2)
def wrapper(): name='周杰倫' def inner(): print(name)#在內層函數中,使用了外層函數的局部變量 return inner #返回函數名 ret=wrapper() ret()
對比(1)和(2)的方式
閉包的優勢:(定義:內層函數使用了外層函數的變量)
1.能夠保護變量不被其餘人侵害
2.保持一個變量常駐於內存
(3)#注意下面的註釋
def wrapper(): name='周杰倫' def inner(): print(name) #在內層函數中使用了外層函數的局部變量 return inner #返回函數名 ret=wrapper() #ret是一個內層函數 ret() #ret是inner,在外層執行的時機是不肯定的,必須保證裏面的name必須存在
(4)
#超級簡易版爬蟲 from urllib.request import urlopen #導入一個模塊 def func(): #獲取到網頁中的內容, content=urlopen('https://www.dytt8.net/').read() return content.decode('gbk') print(func())
(5)#把要反覆打開的網站加載 到內存中,以便快速打開網站,缺點:耗內存
#提高緩存能力版
#解決緩存問題 # #超級簡易版爬蟲 from urllib.request import urlopen #導入一個模塊 #蘋果系統:幹掉數字簽名 # import ssl # ssl._create_default_https_context=ssl._create_unverified_context() def func(): #獲取到網頁中的內容,當網速很慢的時候,反覆的去打開這個網站,很慢 content=urlopen('https://www.dytt8.net/').read() def inner(): return content.decode("gbk") #網頁內容 return inner # return content.decode('gbk') print('開始網絡請求') ret=func() #網絡請求已經完畢 print('網絡請求完畢') print('第一次',ret()[5]) print('第二次',ret()[5]) # print('第一次',ret()) # print('第二次',ret())
3.迭代器
(1)
s='今天下午考試' for c in s: print(c) #主要討論:什麼是可迭代,什麼是不可迭代的?
'''
結果:
今
天
下
午
考
試
'''
(2)
for c in '哼哼哈哈': print(c)#正確 for c in 123: print(c)#錯誤
(3)
dir() 能夠幫助咱們查看xxx數據可以執行的操做
print(dir(str)) #__iter__ print(dir(int)) #沒有__iter__ print(dir(list)) #有__iter__ print(dir(dict)) #有__iter__ print(dir(bool)) #沒有__iter__ for i in True: print(i) #報錯:'bool' object is not iterable
(4)
print(dir(range)) f=open('呵呵',mode='r',encoding='utf-8') print(dir(f)) #正確,文件也是可迭代的
共性:全部帶有__iter__的東西均可以進行for循環,帶有__iter__東西就是可迭代對象
(5)
lst=['賈樟柯','李安','楊德昌','王家衛'] # print('__iter__' in dir(lst)) #判斷迭代器是否在lst中,結果:True it=lst.__iter__() #it是拿到的是迭代器 print(it) #列表的迭代地址:<list_iterator object at 0x0000026309647518> print(it.__next__()) #下一個 print(it.__next__()) #下一個 print(it.__next__()) #下一個 print(it.__next__()) #下一個 # print(it.__next__()) #報錯:下一個報錯,由於列表中只有4個值 StopIteration 中止迭代 it=lst.__iter__() #只能從新獲取迭代器 print(it.__next__()) #下一個,又能夠用了
總結
1.只能向下執行,不能反覆
2.結束的時候會給咱們扔來一個錯誤 StopIteration
3.整合全部的數據類型進行遍歷(int,bool除外)#最大的特色
(6)超級重點
lst=['海爾兄弟','阿童木','葫蘆娃','舒克貝塔','大風車'] #while循環模擬for循環 for el in lst: it=lst.__iter__() #獲取到迭代器0 while 1: #循環 try: #嘗試 el=it.__next__() #拿數據 print(el) except StopIteration: #出了錯誤,意味着數據拿完了 break #結束循環
總結:
1.節省內存
2.惰性機制
3.不能反覆,只能向下執行
hello world!
(7)
官方經過代碼判斷是不是迭代器
藉助於兩個模塊,Iterator迭代器,Iterable可迭代的
from collections import Iterator,Iterable lst=[1,2,3] print(isinstance(lst,Iterator)) #某某某是不是迭代器,False print(isinstance(lst,Iterable)) #某某某是不是可迭代的類型,True it=lst.__iter__() #迭代器必定可迭代,可迭代的東西不必定是迭代器 print(isinstance(it,Iterator)) #某某某是不是迭代器,False print(isinstance(it,Iterable)) #某某某是不是可迭代的類型,True
結果:
False
True
True
True
總結:有些地方還有待完善