"""author = 曹琦"""
迭代器
1.函數(shù)的調(diào)用過程
函數(shù)調(diào)用過程又叫壓棧的過程:每次調(diào)用函數(shù)阿逃,系統(tǒng)都會在內(nèi)存的棧區(qū)間自動開辟一個臨時的內(nèi)存空間悍及,
用來保存在函數(shù)中聲明的局部變量(其中形參也是保存在這個區(qū)域中的)凌节,
當(dāng)函數(shù)調(diào)用結(jié)束施掏,這個內(nèi)存區(qū)域會自動銷毀(這個內(nèi)存中儲存的數(shù)據(jù)也會銷毀)
2.迭代器(iter)
1)什么是迭代器
迭代器是python提供的容器型數(shù)據(jù)類型谎倔,(可變,有序) -- 不關(guān)注
迭代器和之前的列表氛什、字典莺葫、集合、元祖等容器不一樣枪眉,它只能查看元素徙融,而且看一個對于迭代器來說,里面的元素就會少一個
迭代器的值:a.將其他的數(shù)據(jù)轉(zhuǎn)換成迭代器 b.生成器
迭代器中的元素:可以是任何類型的數(shù)據(jù),可以重復(fù)
iter1 = iter('abc')
print(iter1)
iter2 = iter([12,34,'abc',[1,2],{'a': 10},(1,2),{1,3},lambda x: x])
print(iter2)
2)查 - 獲取元素的值
注意:不管以任何形式獲取了迭代器中某個元素的值瑰谜,這個元素都會從迭代器中消失
# a.獲取單個元素
next(迭代器)/迭代器.__next__()欺冀,返回容器中最上面的元素。
iter1 = iter('abc')
print(next(iter1))
print(next(iter1))
print(next(iter1))
# print(next(iter1)) # StopIteration 取完了再取會報錯
# b.遍歷取出迭代器的每一個元素
print('============')
iter3 = iter('abcdef')
next(iter3)
next(iter3)
for item in iter3:
print(item)
print('============')
# print(next(iter3)) # StopIteration
3)什么時候適用迭代器:大量數(shù)據(jù)中某個或者某些數(shù)據(jù)使用過了就不需要在保存了萨脑,這種數(shù)據(jù)就可以使用迭代器來保存隐轩。
生成器
1.什么是生成器
生成器就是迭代器, 但是迭代器不一定是生成器
1)怎么創(chuàng)建生成器
如果函數(shù)中有yield關(guān)鍵字渤早,那么這個函數(shù)就不再是一個普通的函數(shù)职车。
調(diào)用函數(shù)不再是執(zhí)行函數(shù)體,獲取返回值。而是創(chuàng)建這個函數(shù)對應(yīng)的生成器對象
def nums():
print('============')
print(100)
if False:
yield
return 100
gen1 = nums() # 函數(shù)調(diào)用表達(dá)式nums()才是生成器
2)生成器怎么產(chǎn)生數(shù)據(jù)
一個生成器能夠產(chǎn)生多少個數(shù)據(jù)悴灵,就看執(zhí)行完生成器對應(yīng)的函數(shù)體會遇到幾次yield關(guān)鍵字
生成器是在獲取數(shù)據(jù)的時候才會產(chǎn)生數(shù)據(jù)扛芽,執(zhí)行生成器對應(yīng)的函數(shù)的函數(shù)體,直到遇到y(tǒng)ield為止积瞒,
將yield后面的數(shù)據(jù)作為生成器的元素返回川尖,并且會記錄這次產(chǎn)生數(shù)據(jù)函數(shù)體結(jié)束的位置,下次再產(chǎn)生
數(shù)據(jù)的時候茫孔,會接著上次結(jié)束的位置接著往后執(zhí)行...如果從執(zhí)行開始到函數(shù)結(jié)束叮喳,沒有遇到y(tǒng)ield,那么就不會產(chǎn)生數(shù)據(jù)缰贝。
def nums():
print('++++++')
yield 'abc'
print('-------')
yield 100
print('********')
for x in range(5):
yield x
# 創(chuàng)建一個生成器gen2
gen2 = nums()
print('取第一個值')
print(next(gen2))
print('取第二個值')
print(next(gen2))
print('取第三個值')
print(next(gen2))
def nums2():
index = 0
while True:
yield index
index += 2
gen3 = nums2()
for _ in range(10):
print(next(gen3))
print(next(gen3))
print(next(gen3))
生成式
1.生成式
生成式是生成器的另外一種寫法(簡寫)
"""
a.語法1
生成器變量 =(表達(dá)式 for 變量 in 序列) -- 結(jié)果是生成器
列表變量 = [表達(dá)式 for 變量 in 序列] -- 結(jié)果是列表
b.說明:表達(dá)式 -- 可以是值馍悟、變量、運算表達(dá)式剩晴、函數(shù)調(diào)用表達(dá)式等锣咒,只要不是賦值語句都可以
c.展開
def 函數(shù)名():
for 變量 in 序列:
yield 表達(dá)式
gen1 = (x*2 for x in range(5))
print(gen1)
print(next(gen1))
print(next(gen1))
print(next(gen1))
print(next(gen1))
print(next(gen1))
a.語法2:
生成器變量 =(表達(dá)式 for 變量 in 序列 if 條件語句)
b.展開
def 函數(shù)名():
for 變量 in 序列:
if 條件語句:
yield 表達(dá)式
gen2 = (x for x in range(10) if x % 2)
# 5個 1,3,5,7,9
for num in gen2:
print(num)
gen2 = ((x,x*2) for x in range(10) if x % 2)
for num in gen2:
print(num)
gen2 = ((x,x*2) for x in range(10) if x % 2)
list2 = list(gen2)
print(list2)
gen2 = ('num%d' % x for x in range(10) if x % 2)
print(next(gen2))
"""author = 曹琦"""
python中一個py文件就是一個模塊
"""
從封裝的角度看:
函數(shù)是對功能的封裝
模塊可以通過多個函數(shù)對不同的功能進(jìn)行封裝,還可以通過全局變量對數(shù)據(jù)進(jìn)行封裝
模塊
0.模塊的分類:系統(tǒng)模塊(內(nèi)置模塊)赞弥、第三方庫(別人寫的)宠哄、自定義模塊
1.模塊的導(dǎo)入
a.import 模塊名 ------- 可以通過'模塊名.'的方式去使用這個模塊中所有的全局變量
b.from 模塊名 import 全局變量1,全局變量2..... ---- 帶入指定模塊中指定的全局變量嗤攻,導(dǎo)入后直接使用全局變量
注意:import 模塊名 as 新模塊名 ---- 導(dǎo)入模塊并重命名,重命名后诽俯,原名不能使用
from 模塊名 import 全局變量1 as 新名1妇菱,全局變量2 as 新名2.........
import random
import keyword
2.導(dǎo)入方式
=============導(dǎo)入方式1========
# import test
#
# print(test.test1_a*3)
# test.test1_a = 200
#============導(dǎo)入方式2===========
# from random import randint
# print(random(10,30))
# from test import test1_func1,test1_a
# test1_func1()
# =============導(dǎo)入模塊并重命名==========
# import test as Ts
3.導(dǎo)入模塊的原理:當(dāng)代碼執(zhí)行到import或者from - import的時候,會自動將對應(yīng)的模塊中的代碼全部執(zhí)行一遍
同一個模塊導(dǎo)入多次不會重復(fù)執(zhí)行,放心的導(dǎo)入
# print('=============')
# import test
# import test
4.阻止導(dǎo)入:將需要阻止被別的模塊導(dǎo)入的代碼放到一下if語句中
"""
if name == 'main':
需要阻止導(dǎo)入的代碼段
原理:每個模塊都有一個屬于自己的name屬性暴区,用來保存當(dāng)前模塊的模塊名闯团。默認(rèn)情況下name的值
就是模塊對應(yīng)的py文件的文件名。當(dāng)我們直接運行某個模塊的時候仙粱,對應(yīng)的模塊的name會自動變成'main'
其他模塊是默認(rèn)值房交。
"""
異常處理
1.異常:程序錯誤、程序崩潰伐割。程序中某條語句出現(xiàn)異常候味,那么從這條語句開始,后面的代碼不會執(zhí)行隔心,程序直接結(jié)束
2.異常捕獲:程序出現(xiàn)異常的時候白群,程序不崩潰。
1)方式一:捕獲所有異常
try:
代碼段1
except:
代碼段2
其他語句
說明:先執(zhí)行代碼段1硬霍,如果代碼段1不出現(xiàn)異常帜慢,直接執(zhí)行后面的其他語句;
如果出現(xiàn)異常不崩潰直接執(zhí)行代碼段2,然后再執(zhí)行其他語句
list1 = [1,2,3]
try:
print(list1[10])
print('~~~~')
except:
print('出現(xiàn)異常')
print('===========')
2)方式二:捕獲指定的一個或者多個異常粱玲,做相同的處理
try:
代碼段1
except 異常類型:
代碼段2
其他語句
try:
代碼段1
except (異常類型1,異常類型2,.....):
代碼段2
其他語句
先執(zhí)行代碼段1躬柬,如果代碼段1沒出現(xiàn)異常,直接執(zhí)行后面的其他語句抽减;
如果代碼段1出現(xiàn)異常允青,如果這個異常的類型和需要捕獲的異常類型一致朝群,程序不崩潰供屉,直接執(zhí)行代碼段2,然后再執(zhí)行其他語句窄锅;
如果代碼段1出現(xiàn)異常偎箫,如果這個異常的類型和需要捕獲的異常類型不一致木柬,程序直接崩潰。
注意:異常類型要求必須是直接或者間接繼承自Exception類的子類
print('=====方法2=====')
try:
print([1,2,3][10])
print({'a': 10}['b'])
except(KeyError,IndexError):
print('出現(xiàn)異常')
finally:
print('寫遺書')
3)方式三:捕獲不懂類型的異常淹办,并且對不同的異常做不同的處理
try:
代碼段1
except 異常類型1:
代碼段2
except 異常類型2:
代碼段3
...
print('=====方法3=====')
try:
print([1,2,3][10])
print({'a: 10'}['b'])
except IndexError:
print('下標(biāo)越界')
except KeyError:
print('key不存在')
finally:
print('寫遺書')