可迭代对象及异常处理

今日内容概要

  • 常见内置函数02

  • 可迭代对象

  • 迭代器对象

  • for循环的内部原理

  • 异常处理

  • for循环的本质

  • 生成器

     

今日内容详细

一、常见内置函数

# 1.help()  查看注释信息
# help(len)

# 2.id() 返回一串相当于内存地址的数字
# print(id('jason'))

# 3.int() 类型转换、进制数转换

# 4.isinstance() 判断数据类型
print(type('jason') is str)  # 类型转换 比较别扭 不推荐使用
print(isinstance('jason',str)) # True
print(isinstance('jason',int)) # False

# 5.pow() 幂指数
# print(pow(10,2)) # 10**2

# 6.round() 用于四舍五入 近似数
print(round(11,1))  # 第二个参数控制需要保留几位小数部分
# print(round(11.29,1))
# print(round(11.59,1))

# 7.sum()求和
# print(sum([11,2,3,4,5,6,7]))


 

 

二、可迭代对象

# 1.什么叫可迭代对象?
  迭代本质就是更新换代 每一次迭代过程都需要依赖于上一次的结果 需要重新再写只是在原有基础上不断的更新
   例如:游戏的更新其实就是版本的迭代
  """"""
# 单独的循环 不是迭代的概念
import time
while True:
   print(123)
   time.sleep(1)
# 属于迭代
n = 1
while True:
   print(n)
   n += 1   # 就是每一次的更新都需要在上一次的基础上
   
# 迭代取值
l1 =[11,22,33,44,55]
n= 0
while n < len(l1):
   print(l1[n])
   n += 1
这种类型的也是叫迭代取值 就是从左往右取值,然后再从上往下的运行 也是迭代取值的范围

# 2.什么是可迭代对象?
  是指内置有__inter__方法的都可以称之为是可迭代对象
  1.用大白话的意思理解就是:数据可以通过点的方式点出来__inter__(.)
  2.__iter__该类代码的读法:双下inter方法   注意:不能读成inter杠杠、杠杠inter
   
# 3.哪些数据是可迭代对象?
   依次列举并尝试调用__iter__方法即可!!!
i = 11  # 整数不是
f1= 11.11  # 浮点型不是
s ='jason'  # 字符串是
l =[1,2,3,4]   # 列表是
d ={'name':'jason'}  # 字典是
t =(1,2,3,4)   # 元组是
set ={1,2,3,5}  # 集合是
b = True        # 布尔值不是
f = open()      # 文件是
def index():pass   # 普通函数不是

综上所述,属于可迭代对象的有:
   字符串、列表、字典、元组、集合、文件 可迭代对象其实就是为了后续迭代取值做准备(因为后面需要将可迭代对象变成迭代器对象取值)
   
   


   

 

 

三、迭代器对象

# 1.什么是迭代器对象
   就是指可迭代对象用__iter__方法之后生成的结果就是迭代器对象
# 2.迭代器对象的特征
   含有__iter__方法和__next__方法同时满足
# 3.如何理解迭代器对象
  迭代器对象能够极大的节省存储空间
  例如:类似于哆啦A梦的口袋 不用的时候就是只会占一个小口袋的内存空间 需要用的时候我们可以从中取出很多的数据
   也可以类似于老母猪 不要的时候就是一头老母猪的空间 你需要小猪仔的时候 就会给你下一个 不要就不下
   
# 4、迭代器对象如何取值
   调用__next__方法即可 如果取完了则会直接报错!!!
   该方式的出现开辟了一种不需要索引取值的方式(也是for循环底层依据的就是迭代器对象)
   """有了迭代器对象才出现了针对字典和集合的迭代取值操作"""

# 5.迭代器对象补充说明
   1.有很多双下方法其实都有简便写法 但不是全部都有简便的写法
   格式:
   __方法名__ 等价于 方法名()
   最为常见的两个是:
   __iter__   iter()
   __next__   next()
print(s.__iter__()) & print(iter(s))
print(s.__len__())  & print(len(s))
   2.有一些可迭代对象本身也是迭代器对象>>>>:文件对象
   3.可迭代对象调用一次__iter__方法变成迭代器对象  如果继续调用 结果还是迭代器对象本身
   # res = s._iter_()
   res = s.__iter__()
res1 = s.__iter__().__iter__().__iter__()
print(res,res1)
# <str_iterator object at 0x00000000021D8320> <str_iterator object at 0x00000000021D82B0>
   4.迭代取值的要求
 # 第一种在内部变身迭代器对象
# print(s.__iter__().__next__()) # j
# print(s.__iter__().__next__()) # j
# print(s.__iter__().__next__()) # j
# print(s.__iter__().__next__()) # j
# print(s.__iter__().__next__()) # j
# 这种取值方式是先在可迭代对象内部先变身转化成迭代器对象 然后在调用取值 每一次都是这样一个轮回 所以每次取值都是一样的
# 第二种 在外部变身迭代器对象 然后再调用取值就可以一一取值出来了
res = s.__iter__()  # 已经在外面就变身成了迭代器对象了
print(res.__iter__().__next__())   # j 之后再调用还是自身 然后再依次取值
print(res.__iter__().__next__())   # a
print(res.__iter__().__next__())   # s
print(res.__iter__().__next__())   # o
print(res.__iter__().__next__())   # n
   
   

 

 

四、for循环内部原理

l1 =[11,22,33,44,55,66,77,88]
"" 需求:不依赖于for循环 完成对列表元素的取值
例题1:
l1 = [11,22,33,44,55,66,77,88]
res = l1.__iter__()  # 由可迭代对象变成迭代器对象
n = 0
while n < len(l1):
   print(res.__next__())  # 再从迭代器对象中取值
   n += 1
   """"""
# for循环底层原理
# for 变量名 in 可迭代对象:
      #循环体代码
1.会将in后面的数据调用__iter__()变成迭代器对象
    为什么文件对象也可以for循环 因为本身就是迭代器对象 再次调用__iter__自身不变
2.针对产生的迭代器对象依次调用__next__()方法迭代取值
3.当值取完后 会自动处理报错并且退出循环
res =iter(l1)
while True:
   print(next(res))
在使用迭代取值时我们值取完时就会报错 目前我们学的还没有解决第三个问题:就是取值完后会报错的问题

 

 

五、异常处理

# 1.什么是异常?
   异常就是指代码运行出错之后就是异常 异常会导致程序立刻停止
   是我们以后在编程过程中需要极力避免的情况(异常的外号>>>>:bug)

# 2.异常信息的组成部分
  Traceback (most recent call last):
 File "F:/pythonProject10/今日之代码练习.py", line 50, in <module>
   name
NameError: name 'name' is not defined
   1.line关键字所在的一行
   用于提示你代码哪一行出错了 点击前面的蓝色字体可以直接定位
   ""'' 如果报错的信息很长 一般最后一个才是最重要的信息""""""
   2.NameError错误的类型
   代码的报错也可以分为很多种类型
   3.name 'name' is not defined
   具体的报错原因(也是解决报错的答案)
   
# 3.异常的分类
   1.语法异常
   是不被允许犯错的 如果出现了必须立刻改正  
   eg:if分支结构都不会写>>>>
       if 1,while :,....
    2.逻辑异常
   可以允许的 如果出现了尽快修改过来即可
   eg:代码动态获取到了一个字符串类型的数据但是调用了列表的内置方法
       name ='jason'
           print(name.append())
   # 改bug其实就是在重新梳理你的思路
   注意:有时候改bug过程是非常漫长而且痛苦的 此时程序员尽量不要被打扰
   
   公司里面写代码的流程
   1.程序员写完之后自己先大致测试一遍
   2.然后再交给专门的测试人员去测试
   
# 4.异常的类型
比如
名字错误:# NameError
# IndexError 索引错误
# KeyError 键错误
# ValueError   值错误
   
   

 

 

六、异常处理实操

"""有时候针对可能会出错的代码 也可以自己提前写好处理措施"""
   正常情况下代码出错 肯定是直接导致程序停止
   但是也可以自己通过代码来处理 从而避免了程序的停止
   
# 基本语法结构
  try:
       可能会出错的代码
  except 错误的类型1 as e:  # e指代的就是错误的提示信息
   针对性的处理措施
  except2 错误的类型2 as e:
   针对性的处理措施
  except3 错误的类型3 as e:
   针对性的处理措施
   """"""
   
# 错误类型
    很多时候可能自己都不知道会报什么类型的错误
   引出了""万能异常:常见的报错都可以照单全收
  try
     可能会出错的代码
   except Exception as e:
       统一的处理措施
如果我们在代码的开头加try 所有的代码全部写带try的里面 之后万能结尾,这样做的话是写的代码时没有任何意义的

########异常处理使用准则:
1.被检测的代码越少越好
2.能尽量少用就尽量少用

     

 

 

七、异常处理了解

# 1.结合else使用
  当try检测的代码没有发生异常 正常运行完毕之后执行else的子代码
   try
      可能会出错的代码
   except Exception as e:
       统一的处理措施
    else
       可能会出错的代码没有出错 最后走else子代码
# 2.结合finally使用
   无论try检测的代码是否有异常 最后都会执行finally子代码
   try
     name
     except Exception as e:
     print(e)
     finally:
     无论try检测的代码是否有异常 最后都会执行finally子代码
   
# 3.全部整合到一起使用
try
   name
except Exception as e:
   print(e)
else:
   print('没报错 好极了')
finally
   print('管你错不错 都执行')
   
# 4.断言(只要了解即可)
name ='jason'
assert isinstance(name,str)   # True

# 5.主动报错(需要掌握)
raise NameError('也可以自己主动报错')
"""由于是自己主动报错 所以可以非常明确的知道错误的类型"""
     

 

 

八、for循环的本质

# 利用while与异常处理 实现for循环的功能
l1 ={'name':'jason','age':18,'pwd':123}
# 1.先将字典转换成迭代器对象
# res = iter(l1)
# 2.迭代取值
while True:
  print(res.__next__())
  try:
      print(next(res))
  except stopiteration as e:
  # 结束while循环
        break
   

 

 

九、迭代取值与索引取值的对比

1.索引取值
 优势:可以反复获取相同的元素 并且没有固定的方向
 劣势:只能支持有序的容器类型 无序的无法取值兼容性没有迭代取值高
2.迭代取值
优势:兼容所有的容器类型
劣势:取值的顺序永远都是从左往右 并且无法重复获取 去取值就完了
# 真正底层的迭代取值后续可能很少会用 一般都是for循环代替
""""""
迭代器里面的东西都是固定的 每取一个就会少一个 取完就空了

 

 

posted @   一颗平凡的小石头  阅读(115)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示