Python with 工作原理、装饰器、回收机制、内存管理机制、拷贝、作用域等(16)


那么问题来了:同样是不可变序列 , 为什么字符串和元组就支持上述两种操作 , 而偏偏 range序列不支持呢?虽然不能直接修改不可变序列 , 但我们可以将它们拷贝到新的序列上进行操作啊 , 为何 range 对象连这都不支持呢?
且看官方文档的解释:
…due to the fact that rangecan only
thataandandwill
that .
原因是 range 对象仅仅表示一个遵循着严格模式的序列 , 而重复与拼接通常会破坏这种模式…
问题的关键就在于 range 序列的  , 仔细想想 , 其实它表示的就是一个等差数列啊(喵 , 高中数学知识没忘…) , 拼接两个等差数列 , 或者重复拼接一个等差数列 , 想想确实不妥 , 这就是为啥 range 类型不支持这两个操作的原因了 。由此推论 , 其它修改动作也会破坏等差数列结构 , 所以统统不给修改就是了 。
回顾全文 , 我得到了两个偏冷门的结论:range 是可迭代对象而不是迭代器;range 对象是不可变的等差序列 。
迭代器原理剖析:
可迭代对象:
通过索引的方式进行迭代取值 , 实现简单 , 但仅适用于序列类型:字符串 , 列表 , 元组 。对于没有索引的字典、集合等非序列类型 , 必须找到一种不依赖索引来进行迭代取值的方式 , 这就用到了迭代器 。
要想了解迭代器为何物 , 必须事先搞清楚一个很重要的概念:可迭代对象() 。
从语法形式上讲 , 内置有方法的对象都是可迭代对象 , 字符串、列表、元组、字典、集合、打开的文件都是可迭代对象

Python with 工作原理、装饰器、回收机制、内存管理机制、拷贝、作用域等

文章插图
"".__iter__()[].__iter__(){}.__iter__()set().__iter__()().__doc__range(10).__iter__()open("helloworld.txt").__iter__()
迭代器对象:
迭代器对象调用obj.iter()方法返回的结果就是一个迭代器对象() 。迭代器对象是内置有iter和next方法的对象 , 打开的文件本身就是一个迭代器对象 , 执行迭代器对象.iter()方法得到的仍然是迭代器本身 , 而执行迭代器.next()方法就会计算出迭代器中的下一个值 。
迭代器是提供的一种统一的、不依赖于索引的迭代取值方式 , 只要存在多个“值” , 无论序列类型还是非序列类型都可以按照迭代器的方式取值
for循环原理
有了迭代器后 , 我们便可以不依赖索引迭代取值了 , 使用while循环的实现方式如下
goods=['mac','lenovo','acer','dell','sony']i=iter(goods) #每次都需要重新获取一个迭代器对象while True:try:print(next(i))except StopIteration: #捕捉异常终止循环break
for循环又称为迭代循环 , in后可以跟任意可迭代对象 , 上述while循环可以简写为
goods=['mac','lenovo','acer','dell','sony']for item in goods:print(item)
for 循环在工作时 , 首先会调用可迭代对象goods内置的iter方法拿到一个迭代器对象 , 然后再调用该迭代器对象的next方法将取到的值赋给item,执行循环体完成一次循环 , 周而复始 , 直到捕捉异常 , 结束迭代 。
迭代器的优缺点