python_筆記_day12_迭代器_生成器_模塊_異常

day11復(fù)習(xí)

1. 匿名函數(shù)

  • lambda 參數(shù)列表:返回值

2.函數(shù)作為變量

  • 聲明函數(shù)就是聲明類型為function的變量,函數(shù)名是變量
  • 函數(shù)作為參數(shù)(閉包),函數(shù)作為返回值
  • sort\max\min 中的掌握key的使用

3.作用域

  • 全局變量,和局部變量,global,nonlocal
global 變量名
變量名 = 值

一.迭代器

1. 函數(shù)的調(diào)用過程

  • 函數(shù)的調(diào)用過程又叫壓棧過程:每次調(diào)用函數(shù),系統(tǒng)都會在內(nèi)存的棧區(qū)間自動開辟一個(gè)臨時(shí)的內(nèi)存空間,
  • 用來保存函數(shù)中聲明的局部變量(其中形參也是保存在這個(gè)內(nèi)存區(qū)域中的)
  • 當(dāng)函數(shù)調(diào)用結(jié)束,這個(gè)內(nèi)存區(qū)域會自動銷毀(這個(gè)內(nèi)存中存儲的數(shù)據(jù)也會銷毀)

2. 迭代器(iter)

2.1什么是迭代器

  • 迭代器python提供的容器類型的數(shù)據(jù).(可變,有序 -- 不關(guān)注)
  • 迭代器和之前的列表字典集合元組等容器不一樣,它只能查看元素,而且看一個(gè)對于迭代器來說,里面的元素就會少一個(gè)
  • 迭代器的值: a.將其他的數(shù)據(jù)轉(zhuǎn)換成迭代器 b.生成器
  • 迭代器的元素: 任何類型的數(shù)據(jù)都可以,可以重復(fù)
iter1 = iter('abc')
iter2 = iter([12, 32, 'abc'])
iter3 = iter([12, 32, 'abc', [0, 1],{'a':10},(1,2)])

2.2查 - 獲取元素的值

  • 注意: 不管以任何形式獲取了迭代器中的某個(gè)元素值,這個(gè)元素都會從迭代器中消失

2.2.1獲取單個(gè)元素

  • next(迭代器)/迭代器.next() - 返回容器中最上面的元素
print(next(iter1))
print(next(iter1))
print(next(iter1))
# print(next(iter1))     StopIteration
  • 注意當(dāng)容器空了,再next會報(bào)錯(cuò)

2.2.2 遍歷取出跌倒器中的每個(gè)元素

iter4 = iter('abcedfg')
for item in iter4:
    print(item)

2.2.3什么時(shí)候使用迭代器:

  • 多個(gè)數(shù)據(jù)中某個(gè)或者某些數(shù)據(jù)使用過了就不需要再保存了,這種數(shù)據(jù)就可以使用迭代器來保存.

二.生成器

1,什么是生成器:

  • 生成器就是迭代器,但是迭代器不一定是生成器
  • 如果函數(shù)中有yield關(guān)鍵字,那么這個(gè)函數(shù)就不再是一個(gè)普通的函數(shù).

1.1怎么創(chuàng)建一個(gè)生成器

  • 調(diào)用函數(shù)不在是執(zhí)行函數(shù)體,獲取返回值.而是創(chuàng)建這個(gè)函數(shù)對應(yīng)的生成器對象
def nums():
    for x in range(10):
        yield 'a' + str(x)

gen1 = nums()

for x in gen1:
    print(x)

1.2生成器怎么產(chǎn)生數(shù)據(jù)的

  • 一個(gè)生成器能產(chǎn)生多少個(gè)數(shù)據(jù),就看執(zhí)行完生成器對應(yīng)的函數(shù)體會遇到幾次yield關(guān)鍵字
  • 生成器是在獲取數(shù)據(jù)的時(shí)候才會產(chǎn)生數(shù)據(jù),執(zhí)行生成器對應(yīng)的函數(shù)的函數(shù)體,指定遇到yield為止,
  • yield后面的數(shù)據(jù)作為生成器的元素返回,并且會記錄這次產(chǎn)生數(shù)據(jù)函數(shù)體結(jié)束的位置,下次再產(chǎn)生數(shù)據(jù)的時(shí)候
  • 會接著上次結(jié)束的位置接著往后執(zhí)行...如果從函數(shù)開始到函數(shù)結(jié)束,沒有遇到yield,那么就不會產(chǎn)生數(shù)據(jù).
def nums2():
    print('+++++++')
    yield 'abc'
    print('-------')
    yield 100
    for x in range(5):
        yield x
# 創(chuàng)建一個(gè)生成器gen2
gen2 = nums2()
print(next(gen2))
print(next(gen2))
print(next(gen2))
  • 練習(xí) : 寫一個(gè)生成器,能夠產(chǎn)生'stuXXXX'的學(xué)號,stu0000 -- stu9999
def student_gen():
    for x in range(10000):
        yield 'stu' + str(x).zfill(4)

gen33 = student_gen()
print('==========')
for x in range(20):
    print(next(gen33))

2.生成式

  • 生成式是生成器的另一種寫法(簡寫)

2.1語法1:

生成器變量 = (表達(dá)式 for 變量 in 序列)  -- 結(jié)果是生成器
生成器變量 = [表達(dá)式 for 變量 in 序列]  -- 結(jié)果是列表
  • 表達(dá)式 - 可以是值,變量,運(yùn)算表達(dá)式函數(shù)調(diào)用表達(dá)式等,只要不是賦值語句都可以
gen1 = ('stu'+str(x).zfill(4) for x in range(5))
print(next(gen1))
print(next(gen1))

2.2語法2:

生成器變量 = (表達(dá)式 for 變量 in 序列 if 條件語句)
###########################################
def 函數(shù)名():
    for 變量 in 序列:
        if 條件語句
            yield 表達(dá)式
# gen2 = (x for x in range(10) if x % 2)
gen2 = ((x, x*2) for x in range(10) if x % 2)
print(list(gen2))

gen3 = ['num%d' % x for x in range(10) if x % 2]
print(list(gen3))

三.模塊

  • python 中一個(gè)py文件就是一個(gè)模塊

  • 從封裝的角度看: 函數(shù)是對功能的封裝

  • 模塊可以通過多個(gè)函數(shù)對不同的功能封裝,還可以通過全局變量對數(shù)據(jù)封裝

  • 0.模塊的分類:系統(tǒng)模塊(內(nèi)置模塊),第三方庫(別人寫的),自定義模塊

1.模塊的導(dǎo)入

  • a. import 模塊名 /import 模塊名 as 新的模塊名
    可以通過'模塊名.'的方式去使用這個(gè)模塊中所有的全局變量,模塊名可以使用'as'改為新的的名字

  • b. from 模塊名 import 全局變量1 as 新名1,全局變量2 as 新名2,...
    導(dǎo)入模塊中指定的全局變量,導(dǎo)入后直接使用全局變量,全局變量名 as 新名來改變變量的名字,避免重名.

  • 注意: 重命名后,原名不能使用

  • ========= 導(dǎo)入方式1 ========

# import keyword
# import  random
# import math
# import test_moudule
# test_moudule.test1_1 *= 66.66
# print(test_moudule.test1_1)
# test_moudule.test1_fun1()
  • ========= 導(dǎo)入方式2 ========
# from random import randint
# from test_moudule import test1_fun1, test1_1
# test1_fun1()
# print(test1_1)
  • =========導(dǎo)入模塊并重命名========
# import test_moudule as ts
# print(ts.test1_1)
# ts.test1_fun1()
  • =========導(dǎo)入全局變量并重命名=========
# b = 'python'
# from test_moudule import b as t_b
#
# print(b, t_b)

2.導(dǎo)入模塊的原理;

  • 當(dāng)代嗎執(zhí)行到import或者from -import的時(shí)候,會自動將對應(yīng)的模塊中的代碼全部執(zhí)行一遍
  • include不會查重
  • 同一個(gè)模塊導(dǎo)入多次不會執(zhí)行多次(放心導(dǎo)入!)
print('===========')
import test_moudule
import test_moudule
from test_moudule import b
test_moudule.test1_fun1()

3.阻止導(dǎo)入:

  • 將需要阻止被別的模塊導(dǎo)入的代碼放到if語句中
if __name__ == '__main__':
    需要阻止導(dǎo)入的代碼段
  • 原理: 每個(gè)模塊都有一個(gè)屬于自己的neme屬性,來保存當(dāng)前的模塊名.默認(rèn)情況下name的值就是模塊
  • 對應(yīng)的py文件的文件名 .當(dāng)我門直接運(yùn)行某個(gè)模塊的時(shí)候,對應(yīng)的模塊的__name__會自動變成'__main__',其他模塊是默認(rèn)值

四. 異常捕獲

1.異常:

  • 程序錯(cuò)誤程序崩潰.程序中的某條語句出現(xiàn)異常,那么從這條語句開始,后面的代碼不會執(zhí)行,程序直接結(jié)束

2.異常捕獲:

  • 程序出現(xiàn)異常的時(shí)候,程序不崩潰
    '''

方式1:捕獲所有的異常

  • a.語法
try:
    代碼段1
except:
    代碼段2
finally:
    代碼段n     不管什么情況代碼段n都會執(zhí)行,崩潰前也會執(zhí)行,沒有異常,也會執(zhí)行
其他語句
  • b.說明:

先執(zhí)行代碼段1,如果代碼段1不出現(xiàn)異常,直接執(zhí)行后面的其他語句如果出現(xiàn)異常就不崩潰
直接執(zhí)行代碼段2,然后再接著執(zhí)行其他語句

# print('***********')
# # print(int('12a'))
# print('===========')
# print('..............')
#
# while 1:
#     age = int(input('請輸入年齡:'))
list1 = [1, 2, 3]
try:
    print(list1[2])
except:
    print('出現(xiàn)異常')
print('11111111111111')

方式2 捕獲指定的一個(gè)或多個(gè)異常,做相同處理

try:
    代碼段1
except (異常類型1,異常類型2):
    代碼段2 
其他語句

先執(zhí)行代碼段1,如果代碼段1沒出現(xiàn)異常,直接執(zhí)行后面的其他語句
如果代碼段1出現(xiàn)異常,如果這個(gè)異常的類型和需要捕獲的異常類型一致,程序不崩潰,直接執(zhí)行代碼段2,然后再執(zhí)行其他的語句
如果代碼段出現(xiàn)異常,異常類型和需要捕獲的異常類型不一致,程序直接崩潰

  • 注意: 異常類型要求必須是直接或者間接繼承至Exception類的子類
# print('=============方式2============')
# try:
#     print([1,2,3][10])
#     print({'a': 10}['b'])
# except KeyError:
#     print('出現(xiàn)異常')
# # 崩潰
# try:
#     print({'a': 10}['b'])
#     print([1,2,3][10])
# except (KeyError, IndexError):
#     print('出現(xiàn)異常')
# # 出現(xiàn)異常

# try:
#     print([1, 2, 3][10])
#     print({'a': 10}['b'])
# except (KeyError, IndexError):
#     print('出現(xiàn)異常')
# # 出現(xiàn)異常

方式3 捕獲不同類型的異常,并且可以對不同的異常做不同的處理

print('=============方式2============')

'''
try:
    代碼段1
except 異常類型1:
    代碼段2
except 異常類型2:
    代碼段3 
       
其他語句
try:
    print([1, 2, 3][10])
    print({'a': 10}['b'])
except IndexError:
    print('下標(biāo)越界')
except KeyError:
    print('key不存在')
finally:

3 finally: 不管什么情況代碼段n都會執(zhí)行,崩潰前也會執(zhí)行,沒有異常,也會執(zhí)行

try:
    代碼段1
except:
    代碼段2
finally:
    代碼段n     #不管什么情況代碼段n都會執(zhí)行,崩潰前也會執(zhí)行,沒有異常,也會執(zhí)行
其他語句
try:
    print([1, 2, 3][10])
    print({'a': 10}['b'])
except KeyError:
    print('key不存在')
finally:
    print('程序崩潰前我還能搶救下數(shù)據(jù)')
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容