i1 = iter('abc')
print(i1) #
# print(len(i1)) # TypeError: object of type 'str_iterator' has no len()
i2 = iter([10,20,30,40])
print(i2) #
# print(len(i2))
不管以什么样的方式获取到了迭代器中元素,那被获取到的元素一定会从迭代器中消失
获取单个元素:next(迭代器)
print(next(i1)) # 'a'
print(next(i1)) # 'b'
print(next(i1)) # 'c'
# print(next(i1)) # StopIteration
遍历
for x in i1:
print(f'x:{x}')
for x in i2:
print(f'x:{x}')
迭代器转换成列表
i3 = iter('hello')
result = list(i3)
print(result) # ['h', 'e', 'l', 'l', 'o']
# print(next(i3)) # StopIteration
生成器是容器型数据类型(具备创建多个数据的能力,而不是保存多个数据的能力)
打印生成器无法查看所有的元素,生成器也不支持len操作。
如果需要使用生成器中的数据,必须将数据取出来,而且取一个就少一个。
生成器获取数据的方式和迭代器一样。
生成器保存的并不是数据本身,而是产生数据的算法
怎么创建生成器:调用带有yield关键字的函数,就可以得到一个生成器。
def func1():
print('=====')
print('+++++')
if False:
yield
return 100
如果被调用的函数的函数体中有yield,调用函数的时候不会执行函数体,也不会获取函数返回值,而是得到一个生成器对象(函数调用表达式的值就是生成器)
result = func1()
print(result) #
# print(next(result))
示例1:
def func2():
yield 100
yield 200
yield 300
gen2 = func2()
print(next(gen2)) # 100
print(next(gen2)) # 200
print(next(gen2)) # 300
# print(next(gen2)) # StopIteration
示例2:
def func3(subject):
for x in range(1,100):
yield f'{subject}{x:0>3}'
gen3 = func3('python')
print(next(gen3)) # python001
调用函数创建生成器的时候不会执行函数体,获取生成器中的元素的时候才会执行函数体
每次执行函数体的时候从开始位置开始,执行到yield就停下来,并且将yield后面的数据作为获取到的元素。
def func4():
yield 10
yield 20
yield 30
gen4 = func4()
print(next(gen4)) # 10
print(next(gen4)) # 20
print(next(gen4)) # 30
python中一个py文件就是一个模块
前提:被使用模块的模块名(py文件的文件名)必须符合变量名的要求
使用原则:先导入才能使用(能被别的模块使用的内容只能是全局变量)
test1.py:
a = 100
def func1():
print('test中的函数')
name = 'test'
import 模块名 - 导入指定模块,导入后可以通过’模块名.xxx’这个模块中所有的全局变量
import test1
print(test1.a) # 100
print(test1.name) # test
test1.func1() # test中的函数
from 模块名 import 变量1,变量2,… - 导入指定模块中的指定变量,导入后可以直接使用所有指定的变量
from test1 import a,func1
print(a)
func1()
from 模块名 import * - 导入指定模块中所有的变量,导入后可以直接使用所有变量
from test1 import *
print(a)
print(name)
func1()
import 模块名 as 新模块名 - 导入模块的时候对模块重命名,通过’新模块名.xxx’的方式使用模块中所有的全局变量
import test1 as t1
test1 = 22
print(t1.a,t1.name) # 100 test
t1.func1() # test中的函数
print(test1) # 22
from 模块名 import 变量1 as 新变量1,变量2 as 新变量2,… - 对导入的变量重命名
from test1 import a,name as tname
name = '小明'
print(a) # 100
print(name) # 小明
print(tname) # test
不管以什么样式的方式导入了模块,或者模块中的内容。系统都会在导入模块的时候进入对应的模块,将模块中的代码全部执行。
原理存在的问题:可能存在在导入的时候执行一些没有必要执行的代码
导入模块的时候选择性执行代码:
在被导入的模块中添加指定的if语句(if name == ‘main’),将不需要被别的模块执行的代码放入到这个if语句中
if __name__ == '__main__':
# 这个if语句中所有的代码不会被别的模块执行
pass
实例:
download.py:
def download_film(name):
print(f'{name}开始下载:')
print('检查网络')
print('链接服务器')
print('传输数据')
print('保存数据')
print(f'电影{name}下载结束')
if __name__=='__main__':
for x in range(10):
download_film(f'电影{x}')
另外一个模块中调用:
from download import download_film
download_film('肖申克的救赎')
"""
结果:
肖申克的救赎开始下载:
检查网络
链接服务器
传输数据
保存数据
电影肖申克的救赎下载结束
"""
包就是包含__init__.py的文件夹
包就是用来管理py文件,对py文件按照特定的方式进行分类。
需要导入的包和模块:
包:fileManager -> 模块:_init_.py、 operateFile.py、operateJsonFile.py
包:files -> 模块:test2.py
import 包名 - 导入指定的包(必须是包,文件夹无意义),导入后可以通过’包名.xxx’的方式使用__init__.py文件中所有内容
import fileManager
fileManager.create_file() # 创建文件
print(fileManager.m) # 11
import 包名.模块名 - 导入指定包中的指定模块(文件夹也可以)
import fileManager.operateFile
import files.test2
fileManager.operateFile.open_file()
fileManager.operateFile.close_file()
print(files.test2.x)
files.test2.func2()
直接导入包中的模块,然后重命名:
import fileManager.operateFile as file
file.close_file()
file.open_file()
from 包名 import 模块名1,模块名2,…
from fileManager import operateFile, operateJsonFile as json
operateFile.open_file()
from 包名.模块名 import 变量1, 变量2,…
from files.test2 import x, func2
print(x)
func2()
异常就是错误。
执行程序的过程中,会中断程序的执行(让程序提前结束)
exit() - 让程序正常退出
异常捕获 - 让程序在出现异常的时候,不崩溃,还可以接着往后执行
注意:不要滥用异常捕获,如果是因为使用者使用者不当导致程序出现异常,又希望在出现异常程序可以继续执行才使用异常捕获。
结构1
a. 语法:
try:
代码段1(需要捕获异常的代码段)
except:
代码段2(捕获到异常需要执行的代码段)
b. 执行过程:先执行代码段1,如果出现异常马上执行代码段2;如果没有出现异常,就不执行代码段2
c. 实例:
try:
print('abc'[4]) # # IndexError
print('=====')
print('+++++')
except:
print('捕获到异常!')
print('程序结束!')
"""
捕获到异常!
程序结束!
"""
结构2 - 捕获指定异常
try:
代码段1(需要捕获异常的代码段)
except 异常类型:
代码段2(捕获到异常需要执行的代码段)
结构3 - 同时捕获多种异常
try:
代码段1(需要捕获异常的代码段)
except (异常类型1, 异常类型2,…):
代码段2(捕获到异常需要执行的代码段)
结构4 - 同时捕获多种异常
try:
代码段1(需要捕获异常的代码段)
except 异常类型1:
代码段11
except 异常类型2:
代码段22
…