• Python的基本语法(十一)(持续更新)


    迭代器、生成器、模块、包、捕获异常

    1 迭代器

    1. 什么是迭代器(iter)

      迭代器是容器型数据类型;

      打印一个迭代器无法查看这个迭代器中所有的元素,迭代器无法通过len获取元素个数;

      如果想要使用迭代器中的元素,必须将元素从迭代器中取出,而且在取的时候只能从上往下按顺序取,取一个少一个,取出来的数据无法再放回迭代器。

    2. 创建迭代器

      1)用iter将其他序列转换成迭代器

      2)创建生成器

      i1 = iter('abc')
      i2 = iter([10, 20, 30])
      print(i1, i2)	# 
      print(len(i1))	#报错!object of type 'str_iterator' has no len()
      
      • 1
      • 2
      • 3
      • 4
    3. 迭代器的查操作

      不管以什么样的方式获取到了迭代器中元素,那被获取到的元素一定会从迭代器中消失。

      得到就消失!!!

      1)获取单个元素:next(迭代器)

      print(next(i1))     # a
      print(next(i1))     # b
      print(next(i1))     # c
      print(next(i1))     # 报错!StopIteration
      
      • 1
      • 2
      • 3
      • 4

      ​ 2)遍历

      for i in i2:
          print(f'{i}')	#10 20 30
      
      • 1
      • 2

      ​ 3)迭代器转换成序列

      i3 = iter('hello')
      result = list(i3)
      print(result)	#['h', 'e', 'l', 'l', 'o']
      print(next(i3))     # 报错!StopIteration
      
      • 1
      • 2
      • 3
      • 4

    2 生成器

    1. 什么是生成器

      生成器是容器型数据类型(具备创建多个数据的能力,而不是保存多个数据的能力)。

      打印生成器无法查看所有的元素,生成器也不支持len操作。

      如果需要使用生成器中的数据,必须将数据取出来,而且取一个元素就少一个元素。

      生成器获取数据的方式和迭代器一样。

    2. 创建生成器

      生成器保存的并不是数据本身,而是产生数据的算法。

      怎么创建生成器:调用带有yield关键字的函数,就可以得到一个生成器。

      如果被调用的函数的函数体中有yield(不管有没有效,只要有yield),调用函数的时候不会执行函数体,也不会获取函数返回值,而是得到一个生成器对象(函数调用表达式的值就是生成器)

    3. 创建生成器对应的函数

      生成器创建数据的个数和数据的值,由在执行生成器对应的函数的函数体的时候会遇到几yield,每次遇到yield的时候对应的数据来决定。

      是次数,不是个数!!!

      ​ 执行函数体会遇到几次yield对应的生成器就可以创建多少个数据;

      ​ 每次遇到yield,yield后面的值是什么,对应的元素的值就是什么。

      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))	#报错!
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      def func3(sub):
          for i in range(1, 100):
              yield f'{sub}{i:0>3}'
      
      
      gen3 = func3('python')	#python001
      
      print(next(gen3))
      for i in gen3:
          print(f'i:{i}')
      结果:
      i:python002
      ...
      i:python099
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
    4. 生成器产生数据的原理

      调用函数创建生成器的时候是不会执行函数体,获取生成器中的元素才会执行函数体。

      每次在执行函数体的时候从开始位置开始,执行到yield就停下来,并且将yield后面的数据作为获取到的元素。

      def func4():
          print('====1====')
          yield 10
          print('====2====')
          yield 20
      
      
      gen4 = func4()
      print(next(gen4))
      print('----')
      print(next(gen4))
      结果:
      ====1====
      10
      ----
      ====2====
      20
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17

    3 模块

    1. 什么是模块

      python中一个py文件就是一个模块。

    2. 怎么在一个模块中使用另外一个模块内容

      前提:被使用的模块的模块名(py文件的文件名)必须符合变量名的要求。

      使用原则:先导入才能使用(能被别的模块使用的内容只能是全局变量)。

    3. 导入模块

      1)导入方式1🌸

      import 模块名		导入指定模块,导入可以通过'模块名.xxx'的方式使用这个模块中所有的全局变量
      
      • 1
      import test01
      
      print(test01.a)
      test01.func1()
      print(test01.name)
      
      • 1
      • 2
      • 3
      • 4
      • 5

      2)导入方式2🌸

      from 模块名 import 变量1,变量2,变量3,...		导入指定模块中的指定变量,导入后可以直接使用所有指定的变量
      
      • 1
      from test01 import a, func1, name
      
      print(a)
      func1()
      print(name)
      
      • 1
      • 2
      • 3
      • 4
      • 5

      3)导入方式3🌸

      from 模块名 import *		导入指定模块中所有的变量,导入后可以直接使用所有变量
      
      • 1
      from test01 import *
      
      print(a)	#100
      func1()		#test中的函数
      print(name)	#test
      
      • 1
      • 2
      • 3
      • 4
      • 5

      4)导入方式4🌸

      import 模块名 as 新模块名		导入模块的时候对模块重命名,通过'新模块名.xxx'的方式使用模块中所有的全局变量
      
      • 1

      1)模块名与模块里的变量冲突

      2)名字太长或者不习惯想换一个

      import test01 as te
      
      print(te.a)
      te.func1()
      print(te.name)
      
      • 1
      • 2
      • 3
      • 4
      • 5

      5)导入方式5🌸

      from 模块名 import 变量1 as 新变量1,变量2 as 新变量2,...		对导入的变量重命名,重命名只对此次导入使用有效
      
      • 1
      from test01 import a as nam
      print(nam)
      
      • 1
      • 2
    4. 导入模块的原理

      不管以什么样的方式导入了模块或者模块中的内容,系统都会在导入模块的时候进入对应的模块,将模块中的代码执行一遍

      如果只导入一部分变量也会执行整个模块文件。

      ​ 原理存在的问题:可以存在在导入模块的时候执行一些完全没有必要执行的代码。

      ​ 导入模块的时候选择性执行代码:

      ​ 在被导入的模块中添加指定的if语句(if __name__ == '__main__':)(_ _读法:当嘚儿),将不 需要被别的模块执行的代码放入到这个if语句中。

    4 包

    1. 什么是包

      包就是包含_ _ init _ _.py文件的文件夹。请添加图片描述
      在这里插入图片描述
      ​ 包就是用来管理py文件,对py文件按照特定的方式进行分类。

    2. 怎么使用包中的内容
      在这里插入图片描述

      _ _ init _ _.py文件有变量b=12;

      time1.py有变量a=100

      1)导入方式1🌸

      import 包名		导入指定的包(必须是包,文件夹无意义),导入后可以通过'包名.xxx'的方式使用__init__.py文件中的所有内容
      
      • 1
      import timeMangen
      print(timeMangen.b) #12
      
      • 1
      • 2

      2)导入方式2🌸

      import 包名.模块名 	导入指定包中的指定模块(文件夹也可以使用)通过'包名.模块名.xxx'(太麻烦了,重命名变简单些)
      
      • 1

      直接导入包中的模块,然后重命名

      import timeMangen.time1
      print(timeMangen.time1.a)	#100
      
      import timeMangen.time1 as t1
      print(t1.a)		#100
      
      • 1
      • 2
      • 3
      • 4
      • 5

      3)导入方式3🌸

      from 包名 import 模块名1,模块名2,...	直接导入包中指定多个模块
      
      • 1

      ‘模块名.变量名’

      from timeMangen import time1
      print(time1.a)	#100
      
      • 1
      • 2

      4)导入方式4🌸

      from 包名.模块名 import 变量1,变量2,...		导入指定包中指定模块中的指定内容
      
      • 1

      直接使用变量

      from timeMangen.time1 import a
      print(a)	#100
      
      • 1
      • 2
    3. _ _ init _ _.py文件

      1)创建快捷键

      在这里插入图片描述

      在_ _ init _ _.py里面先导入,化简

      1)先在__init__.py文件导入
      from timeMangen.img.img import c
      
      2)再在需要导入的文件直接导入变量
      from timeMangen import c,b
      
      3)使用
      print(b)
      print(c)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

      2)封装通用工具

      把通用的工具写在该文件中。

      也可以不写

    5 异常捕获

    1. 异常

      异常就是错误!

      执行程序的过程中,如果出现异常,会中断程序的执行(让程序提前结束)。

      exit()让程序正常退出。

    2. 异常捕获

      让程序在出现异常的时候,不崩溃,还可以接着走往后执行。

      注意:不要滥用异常捕获。如果是因为使用者使用不当导致程序出现异常,又希望在出现异常程序可以继续执行才使用异常捕获。

      1)结构1🌸

      try:
          代码段1(需要捕获异常的代码段)
      except:
          代码段2(捕获到异常需要执行的代码段)
      
      • 1
      • 2
      • 3
      • 4

      执行过程:先执行代码段1,如果出现异常直接马上执行代码段2;如果没有出现异常,就不执行代码段2

      try:
          age = int(input('请输入年龄:'))
          if age >= 18:
              print('成年')
          else:
              print('未成年')
      except:
          print('年龄输入异常!')
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

      捕获所有的异常。

      2)结构2🌸

      try:
          代码段1(需要捕获异常的代码段)
      except 异常类型:
          代码段2(捕获到异常需要执行的代码段)
      
      • 1
      • 2
      • 3
      • 4

      捕获指定异常。最保险。

      3)结构3🌸

      try:
          代码段1(需要捕获异常的代码段)
      except (异常类型1,异常类型2,...):
          代码段2(捕获到异常需要执行的代码段)
      
      • 1
      • 2
      • 3
      • 4

      同时捕获多种异常。

      4)结构4🌸

      try:
          代码段1(需要捕获异常的代码段)
      except 异常类型1:
          代码段2(捕获到异常需要执行的代码段)
      except 异常类型2:
          代码段3(捕获到异常需要执行的代码段)
      ...    
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

      捕获所有的异常。

      2)结构2🌸

      try:
          代码段1(需要捕获异常的代码段)
      except 异常类型:
          代码段2(捕获到异常需要执行的代码段)
      
      • 1
      • 2
      • 3
      • 4

      捕获指定异常。最保险。

      3)结构3🌸

      try:
          代码段1(需要捕获异常的代码段)
      except (异常类型1,异常类型2,...):
          代码段2(捕获到异常需要执行的代码段)
      
      • 1
      • 2
      • 3
      • 4

      同时捕获多种异常。

      4)结构4🌸

      try:
          代码段1(需要捕获异常的代码段)
      except 异常类型1:
          代码段2(捕获到异常需要执行的代码段)
      except 异常类型2:
          代码段3(捕获到异常需要执行的代码段)
      ...    
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

      同时捕获多种异常。

  • 相关阅读:
    【正则表达式总结】
    八、PL/SQL 记录
    【CSDN竞赛题解】判断题:脉冲调制编码(PCM),选择题:以下哪一种常见的文件格式与增量编码无关?哪一项不是自适应差分脉冲调制编码(ADPCM..,编程题:小球游戏,王子闯闸门
    Java_汉诺塔
    mybatis初体验(细节满满)
    Qt网络编程之搭建Udp通信【单播、组播、广播】
    图解网络(三)——TCP篇06
    如何用 Electron 打包chatgpt-plus.top并生成mac客户端
    SPEL表达式注入分析
    char *, char **,char a[] ,char *a[]啥啥分不清楚?
  • 原文地址:https://blog.csdn.net/m0_69100942/article/details/126147990