day13 迭代器、生成器、模塊

from copy import copy

1.什么是迭代器(iter)

"""
迭代器是容器型數(shù)據(jù)類(lèi)型, 只能通過(guò)類(lèi)型轉(zhuǎn)換和生成器來(lái)獲得迭代器對(duì)象

迭代器存儲(chǔ)數(shù)據(jù)的特點(diǎn): 同時(shí)可以保存多個(gè)數(shù)據(jù),沒(méi)有辦法直接查看,而是需要先將數(shù)據(jù)從迭代器中取出來(lái)(取出來(lái)之后不能再放回去)
"""

所有的容器都可以轉(zhuǎn)換成迭代器

iter1 = iter([10, 20, 30, 40])
print(iter1)

iter2 = iter('abc')
print(iter2)

iter3 = iter({'name': '張三', 'age': 18, 'gender': '男'})
print(iter3)

iter4 = copy(iter1)
print(iter4)

2.獲取迭代器中的元素

"""
(**)無(wú)論通過(guò)什么樣的方式,只要是將迭代器中的某個(gè)元素拿到了,那么這個(gè)元素在迭代器中就不存在了
"""
list1 = list(iter1)
print(list1)
list2 = list(iter1)
print(list2)

1)遍歷

iter5 = iter('hello!')
for x in iter5:
print(f'x: {x}')

print(list(iter5)) # []

2)獲取單個(gè)元素

"""
next(迭代器對(duì)象) - 獲取迭代器中的一個(gè)元素(當(dāng)前最前面的那個(gè)元素)
迭代器對(duì)象.next() - 獲取迭代器中的一個(gè)元素(當(dāng)前最前面的那個(gè)元素)
"""
iter3 = iter({'name': '張三', 'age': 18, 'gender': '男'})

print(next(iter3)) # name
print(next(iter3)) # age
print(next(iter3)) # gender

print(next(iter3)) # 報(bào)錯(cuò): StopIteration

print('===============================')

iter4 = iter([1, 2, 3, 4, 5, 6, 7])
next(iter4)
next(iter4)
print('++++++++++')
for x in iter4:
print(f'x: {x}')

len 無(wú)法獲取迭代器的長(zhǎng)度

iter5 = iter('hello world!')

print(len(iter5))

1.什么是生成器

"""
a.概念1
生成器就是迭代器

b.概念2
調(diào)用一個(gè)帶有 yield 關(guān)鍵字的函數(shù)就可以得到一個(gè)生成器
"""

def func1():
print('++++')
print('----')
yield

result = func1()
print('result:', result)

2. 生成器產(chǎn)生數(shù)據(jù)(生成器中的元素怎么產(chǎn)生)

"""
生成器能生產(chǎn)多少數(shù)據(jù)就看執(zhí)行生成器對(duì)應(yīng)的函數(shù)的函數(shù)體會(huì)遇到幾次 yield ; yield 后面表達(dá)式的值就是生成器能夠產(chǎn)生的數(shù)據(jù)
"""

示例一:創(chuàng)建一個(gè)生成器可以產(chǎn)生3個(gè)數(shù)據(jù)分別是:10, 100, 78

def create_gender1():
yield 10
yield 100
yield 78

gen1 = create_gender1()
print(list(gen1))

3. 生成器產(chǎn)生數(shù)據(jù)的原理

"""
當(dāng)獲取生成器元素的時(shí)候,會(huì)自動(dòng)調(diào)用生成器關(guān)聯(lián)的函數(shù)。第一次從函數(shù)開(kāi)始的地方開(kāi)始執(zhí)行,直到遇到 yield 為止,
并且將 yield 后面的值作為獲取到的數(shù)據(jù);后面每次都是從上一次結(jié)束的位置開(kāi)始執(zhí)行,直到遇到 yield。如果從開(kāi)始執(zhí)行到函數(shù)結(jié)束都沒(méi)有遇到 yield 就不會(huì)產(chǎn)生數(shù)據(jù)(如果是用 next 去取的數(shù)據(jù)這個(gè)時(shí)候會(huì)報(bào)錯(cuò))
"""

def create_gender2():
print('函數(shù)開(kāi)始')
yield 10
print('++++++')
yield 98
print('========')
yield 100
print('函數(shù)結(jié)束')

gen2 = create_gender2()
print('========第1次========')
print(f'元素: {next(gen2)}')
print('========第2次========')
print(f'元素: {next(gen2)}')
print('========第3次========')
print(f'元素: {next(gen2)}')
print('========第4次========')

print(f'元素: {next(gen2)}') # 報(bào)錯(cuò):StopIteration

可以不斷產(chǎn)生數(shù)據(jù)

def create_gender3():
num = 0
while True:
num += 1
yield num

gen3 = create_gender3()
print(next(gen3))

練習(xí):寫(xiě)一個(gè)產(chǎn)生4位驗(yàn)證碼的生成器(驗(yàn)證碼有隨機(jī)的4位數(shù)字和字母組成)

from random import choices

def code_gender4():
alp = 'abcdefghijklmnopqrstuvwxyz'
str1 = alp + alp.upper() + '0123456789'
while True:
yield ''.join(choices(str1, k=4))

gen4 = code_gender4()
print(next(gen4))
print(next(gen4))

注意:每次調(diào)用函數(shù)都是在創(chuàng)建一個(gè)新的生成器對(duì)象

def create_gender5():
for x in range(5):
yield x

print(next(create_gender5())) # 0
print(next(create_gender5())) # 0

gen5 = create_gender5()
print(next(gen5)) # 0
print(next(gen5)) # 1

1. 生成式

"""
生成式就是生成器的簡(jiǎn)寫(xiě)

列表推導(dǎo)式的[]變成()就變成了生成式
"""
list1 = [x*2 for x in range(5)]
print(list1) # [0, 2, 4, 6, 8]

gen1 = (x*2 for x in range(5))
print(gen1) # <generator object <genexpr> at 0x103dba050>
print(next(gen1)) # 0
print(next(gen1)) # 2

gen1 = (x*2 for x in range(5)) 相當(dāng)于:

def func():
for x in range(5):
yield x*2

gen1 = func()

1. 什么是模塊

"""
一個(gè)模塊就是一個(gè)py文件, py文件的文件名就是模塊名
"""

2. 在一個(gè)模塊中使用另外一個(gè)模塊的內(nèi)容

"""

  1. 哪些能用:所有在指定if語(yǔ)句外的全局變量
  2. 怎么使用: 需要先導(dǎo)入模塊

import 模塊名 - 導(dǎo)入后可以使用所有的全局變量;以 '模塊名.變量' 來(lái)使用變量
from 模塊名 import 變量1, 變量2, 變量3,... - 導(dǎo)入后可以使用指定的變量; 直接使用變量
from 模塊名 import * - 導(dǎo)入后可以使用所有的全局變量; 直接使用變量 (不推薦使用)

import 模塊名 as 新模塊名 - 導(dǎo)入模塊的時(shí)候給模塊取別名,以后使用模塊的時(shí)候使用新名字
from 模塊名 import 變量1 as 新變量1, 變量2 as 新變量2, 變量3,... - 給指定變量取別名
"""

示例一:import直接導(dǎo)入模塊

import test1

print(test1.a)

print(test1.b)

test1.func1()

示例二:form-import導(dǎo)入模塊中的變量

from test1 import a, func1

print(a)

func1()

# 沒(méi)有導(dǎo)入的變量不能使用

# print(test1.b) # NameError: name 'test1' is not defined

# print(b) # NameError: name 'b' is not defined

示例三:form-import * 導(dǎo)入模塊中的變量

from test1 import *

print(a)

print(b)

func1()

示例四: 給模塊取別名

import test1 as m_test1

import teacherStudentSystemManager as ts_manager

test1 = 10

print(test1) # 10

print(m_test1.a)

m_test1.func1()

示例五: 給模塊中的變量取別名

from test1 import a as t_a, b
a = 50
sum1 = 0
for x in range(a+1):
sum1 += x
print(sum1)

print(f'test1中的a的值:{# 1.導(dǎo)入模塊的原理
"""
當(dāng)使用import或者from-import 導(dǎo)入模塊的時(shí)候,系統(tǒng)會(huì)自動(dòng)將被導(dǎo)入的模塊中所有的代碼都執(zhí)行一遍
"""

import test2

from test2 import a

2. 重復(fù)導(dǎo)入同一個(gè)模塊,模塊中的內(nèi)容只會(huì)執(zhí)行一次

import test2

import test2

面試題1:說(shuō)說(shuō) improt 和 include 的區(qū)別?

面試題2:python中循環(huán)導(dǎo)入的問(wèn)題

from test3 import jiecheng

print(jiecheng(9))

3. 怎么選擇性的執(zhí)行被導(dǎo)入的內(nèi)容

"""
在被導(dǎo)入的模塊中添加if語(yǔ)句,將不希望被其他模塊執(zhí)行的代碼放到if語(yǔ)句中。

if 語(yǔ)句:
if name == 'main':
不希望被其他模塊執(zhí)行的代碼

原理:
每個(gè)模塊都有一個(gè)屬性:name,這個(gè)屬性是用來(lái)保存當(dāng)前模塊的名字;name默認(rèn)值就是模塊名(模塊對(duì)應(yīng)的py文件的文件名)。當(dāng)我們直接執(zhí)行某個(gè)模塊的時(shí)候,這個(gè)模塊的 name屬性就會(huì)自動(dòng)變成 'main'
"""
import test4

def main():
print('程序開(kāi)始的代碼')

if name == 'main':
main()

t_a}, 當(dāng)前模塊中的a:{a}')

1.什么是包

"""
包就是一種特殊的文件夾(a.里面的文件都是py文件 b.自帶一個(gè) init.py 的文件)
"""

1.直接導(dǎo)入

示例一:通過(guò)包直接導(dǎo)入模塊

from shape import circle

r = 10

print(circle.area(r))

示例二:通過(guò)包導(dǎo)入模塊中的數(shù)據(jù)

from shape.circle import area

print(area(10))

2.導(dǎo)入的定制

import shape

from shape import c_area, r_area, func
print(c_area(10))
print(r_area(20, 4))

func()

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。