Python入门-迭代器
在说迭代器之前,首先来简单说一下函数名的运用以及闭包的概念和应用,有助于我们理解以后的知识.
一.函数名的运用
函数名是一个变量,但它是一个特殊的变量,与括号配合可以执行函数的变量.
1.函数名的内存地址
def func():
print('呵呵')
print(func)
结果:
<function func at 0x000000000241FA60>
2.函数名可以赋值给其他变量
def func():
print('呵呵')
print(func)
a = func #把函数当成一个变量赋值给另一个变量
a() #函数调用 func()
3.函数名可以当做容器类的元素
def func1():
print('呵呵')
def func2():
print('呵呵')
def func3():
print('呵呵')
def func4():
print('呵呵')
lst = [func1,func2,func3,func4] for i in lst:
i()
4.函数名可以当做函数的参数
def func():
print'你好')
def func2(fn):
print('我是func2')
fn() #执行传递过来的fn
print('我是func2')
func2(func) #把函数当成参数传递给func2的参数fn
5.函数名可以作为函数的返回值
def func1():
print('这里是func1')
def func2():
print('这里是func2')
print('这里是func1')
return func2
fn = func1() #执行函数1,返回函数func2,这时fn指向的就是上面的函数func2
fn() #执行上面返回的函数
二.闭包
什么是闭包? 闭包就是内层函数对外层函数(非全局)的变量的引用.
def outer():
name = '周星驰'
def inner():
print(name)
inner()
outer()
结果:
周星驰
我们可以使用__closure__来检测函数是否是闭包,使用函数名.__closure__返回cell就是闭包,返回None就不是.
def outer():
name = '周星驰'
def inner():
print(name)
print(inner.__closure__) #(<cell at 0x00000000023476A8: str object at 0x000000000234BAB0>,)
outer()
如何在函数外部调用内部函数呢?
def outer():
name = '周星驰'
def inner():
print(name)
return inner
fn = outer() #访问外部函数,获取到内部函数的函数地址
fn() #访问内部函数
如果是多层嵌套呢?很简单,只需要一层一层的往外层返回就行了
def func1():
def func2():
def func3():
print('嘿嘿')
return func3
return func2
func1()()()
由它我们可以引出闭包的好处,由于我们在外界可以访问内部函数,那这个时候内部函数访问的时间和时机就不一定了,因为在外部我们选择在任意的时间去访问内部函数,这个时候想一想,我们之前说过,如果一个函数执行完毕,则这个函数中的变量以及局部命名空间中的内容都将会被销毁,在闭包中,如果变量被销毁了,那内部函数将不能正常执行,所以,python规定,如果你在内部函数中访问了外层函数中的变量,那么这个变量将不会被销毁,将会常驻内存中,也就是说,使用闭包可以保证外层函数中的变量在内存中常驻,这样做有什么好处呢?非常大的好处,我们来看一个关于爬虫的代码:
from urllib.request import urlopen
def but():
content = urlopen("http://www.xiaohua100.cn/index.html").read()
def get_content():
return content
return get_content
fn = but() # 这个时候就开始加载校花100的内容
# 后面需要用到这里面的内容就不需要在执行非常耗时的网络连接操作了
content = fn() # 获取内容
print(content)
content2 = fn() # 重新获取内容
print(content2)
综上所述,闭包的作用就是让一个变量能够常驻内存,供后面的程序使用
三.迭代器
之前一直在用可迭代对象就行迭代操作,那么到底什么是可迭代对象,本小节主要讨论可迭代对象,首先我们先回顾一下目前我们所熟知的可迭代对象有哪些:
str,list,tuple,dict,set.那为什么我们可以称他们为可迭代对象呢?因为他们都遵循了可迭代协议,什么是可迭代协议,首先我们先看一段错误代码:
# 对的
s = "abc"
for c in s:
print(c)
# 错的
for i in 123:
print(i)
结果:
Traceback (most recent call last):
File "/Users/sylar/PycharmProjects/oldboy/iterator.py", line 8, in
<module>
for i in 123:
TypeError: 'int' object is not iterable
注意看报错信息中有这样一句话,'int' object is not iterable.翻译过来就是整数类型对象是不可迭代的,iterable表示可迭代的,表示可迭代协议,那么如何进行验证你的数据类型是否符合可迭代协议,我们可以通过dir函数来查看类中定义好的所有方法.
s = '哈哈哈'
print(dir(s)) #可以打印对象中的方法和函数
print(dir(str)) #也可以打印类中声明的方法和函数
在打印结果中,寻找__iter__,如果找到,那么这个类的对象就是一个可迭代对象.
['__add__', '__class__', '__contains__', '__delattr__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__',
'__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__',
'__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode',
'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index',
'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower',
'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join',
'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind',
'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines',
'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
我们发现在字符串中可以找到__iter__,继续看一下list,tuple,dict,set
print(dir(tuple))
print(dir(list))
print(dir(open("护士少妇嫩模.txt"))) # 文件对象
print(dir(set))
print(dir(dict))
结果:
['__add__', '__class__', '__contains__', '__delattr__', '__dir__',
'__doc__, '__eq__', '__format__', '__ge__', '__getattribute__',
'__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__',
'__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count',
'index']
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__',
'__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__',
'__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__',
'__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count',
'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
['_CHUNK_SIZE', '__class__', '__del__', '__delattr__', '__dict__',
'__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__',
'__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__',
'__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__ne__',
'__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_checkClosed',
'_checkReadable', '_checkSeekable', '_checkWritable', '_finalizing',
'buffer', 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno',
'flush', 'isatty', 'line_buffering', 'mode', 'name', 'newlines', 'read',
'readable', 'readline', 'readlines', 'seek', 'seekable', 'tell',
'truncate', 'writable', 'write', 'writelines']
['__and__', '__class__', '__contains__', '__delattr__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__',
'__hash__', '__iand__', '__init__', '__init_subclass__', '__ior__',
'__isub__', '__iter__', '__ixor__', '__le__', '__len__', '__lt__',
'__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__',
'__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__',
'__str__', '__sub__', '__subclasshook__', '__xor__', 'add', 'clear',
'copy', 'difference', 'difference_update', 'discard', 'intersection',
'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop',
'remove', 'symmetric_difference', 'symmetric_difference_update', 'union',
'update']
['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__',
'__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__',
'__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys',
'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
我们发现这几个可以进行for循环的东西都有__iter__函数,包括range也有,可以自己试一下.
这是查看一个对象是否是可迭代对象的第一种方法,我们还可以通过isinstence()函数来查看一个对象是什么类型
l = [1,2,3]
l_iter = l.__iter__()
from collections import Iterable
from collections import Iterator
print(isinstance(l,Iterable)) #True
print(isinstance(l,Iterator)) #False
print(isinstance(l_iter,Iterator)) #True
print(isinstance(l_iter,Iterable)) #True
综上所述,我们可以确定,如果对象中有__iter__函数,那么我们认为这个对象遵守了可迭代协议,就可以获取到相应的迭代器,这里的__iter__是帮助我们获取到对象的迭代器,我们使用迭代器中的__next__()来获取到一个迭代器中的元素,那么我们之前讲的for的工作原理到底是什么?
s = "我爱北京天安门"
c = s.__iter__() # 获取迭代器
print(c.__next__()) # 使用迭代器进行迭代. 获取一个元素 我
print(c.__next__()) # 爱
print(c.__next__()) # 北
print(c.__next__()) # 京
print(c.__next__()) # 天
print(c.__next__()) # 安
print(c.__next__()) # 门
print(c.__next__()) # StopIteration
for 循环机制:
for i in [1,2,3]:
print(i)
使用while循环+迭代器来模拟for循环(必须要掌握)
lst = [1,2,3]
lst_iter = lst.__iter__()
while True:
try:
i = lst_iter.__next__()
print(i)
except StopIteration:
break
总结:
iterable:可迭代对象,内部包含__iter__()函数
iterator:迭代器,内部包含__iter__()同时包含__next__()
迭代器的特点:
1.节省内存
2.惰性运算
3.不能反复,只能向下执行
我们可以把要迭代的内容当成子弹,然后呢,获取到迭代器__iter__(),就把子弹都装在弹夹中,然后发射就是__next__()把每一个子弹(元素)打出来,也就是说,for循环的时候,一开始的时候是__iter__()来获取迭代器,后面每次获取元素都是通过__next__()来完成的,当程序遇到Stopiteration将结束循环.
Python入门-迭代器的更多相关文章
- Python入门-迭代器和生成器
迭代演示 # 传统数据生成缺陷演示,编号操作未全部使用,会占用内存 #合适的做法,是需要的时候再生产,而不是全部生成好了再用 def generator(maxnum): print("[代 ...
- Python 入门之 Python三大器 之 迭代器
Python 入门之 Python三大器 之 迭代器 1.迭代器 (1)可迭代对象: <1> 只要具有__ iter __()方法就是一个可迭代对象 (我们可以通过dir()方法去判断一个 ...
- Python自动化运维之1、Python入门
Python简介 python是吉多·范罗苏姆发明的一种面向对象的脚本语言,可能有些人不知道面向对象和脚本具体是什么意思,但是对于一个初学者来说,现在并不需要明白.大家都知道,当下全栈工程师的概念很火 ...
- Python语言学习之Python入门到进阶
人们常说Python语言简单,编写简单程序时好像也确实如此.但实际上Python绝不简单,它也是一种很复杂的语言,其功能特征非常丰富,能支持多种编程风格,在几乎所有方面都能深度定制.要想用好Pytho ...
- Python入门篇-高阶函数
Python入门篇-高阶函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.高级函数 1>.First Class Object 函数在Python中是一等公民 函数也 ...
- Python入门篇-生成器函数
Python入门篇-生成器函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.生成器概述 1>.生成器generator 生成器指的是生成器对象,可以由生成器表达式得到, ...
- Python入门篇-函数、参数及参数解构
Python入门篇-函数.参数及参数解构 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.函数概述 1>.函数的作用即分类 函数 数学定义:y=f(x) ,y是x的函数,x ...
- Python入门篇-内建函数
Python入门篇-内建函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.常见的内建函数案例 1>.标识id 返回对象的唯一标识,CPython返回内存地址. #!/ ...
- Python入门篇-解析式、生成器
Python入门篇-解析式.生成器 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.列表解析式(List Comprehension) 1>.列表解析式语法 语法 [ 返回 ...
随机推荐
- 循环神经网络中BFTT的公式推导
一.变量定义 此文是我学习BFTT算法的笔记,参考了雷明<机器学习与应用>中的BFTT算法推导,将该本书若干个推导串联起来,下列所有公式都是结合书和资料,手动在PPT上码的,很费时间,但是 ...
- Kettle 值映射
在费用转换里面做了两个值映射.一个是编码.一个是名称.其中两个值映射设置不一样效果不一样. 第一个编码映射 目标字段名不为空,则表示会新增字段.其中复核源值条件的都会转换为目标值,不符合条件的会用[不 ...
- python之类与对象(5)
6. 类的多继承与超继承 6.1 多继承 python的类还有一个特点,就是可以继承多个类.但是我们作为测试人员,在实际中很少用到这个多继承,这里不就详细(一直都不详细,hhhh)写了.上代码: #! ...
- 认识CSS中高级技巧之元素的显示与隐藏
前端之HTML,CSS(八) CSS高级技巧 元素的显示与隐藏 CSS中有三个属性可以设置元素的显示于隐藏,分别是:display.visibility和overflow. display 隐藏元素: ...
- FreeRTOS-01移植及任务创建和删除
根据正点原子FreeRTOS视频整理 单片机:STM32F207VC FreeRTOS源码版本:v10.0.1 任务创建和删除API函数: 工程列表: 1. main.c /**/ #include ...
- 用selenium工具做软件自动化测试的面试题及答案
1.selenium中如何判断元素是否存在? 答:isElementPresent 2.selenium中hidden或者是display = none的元素是否可以定位到? 答:不可以定位到 3.s ...
- element-ui table多选CheckBox参数解析
element-UI里的table表格与多选框CheckBox的组合很常用,官网也给了很多参数,自己总结了一下,方便日后使用 1.简易用法,没有附加的功能 要在表格里使用CheckBox很简单,只需设 ...
- js控制a标签点击事件 触发下载
问题背景,动态获取data把url赋值到a标签的url中,让a标签自动下载 首先想到的应该是$('xxx').click(), 查资料明白:js中的$(...).click()事件只能触发绑定的onC ...
- (转)Heartbeat+DRBD+NFS高可用案例
原文:http://9861015.blog.51cto.com/9851015/1939521--------------------------------Heartbeat+DRBD+NFS高可 ...
- java NIO学前准备
之前一直对NIO感兴趣,无奈对IO的很多概念很模糊,所以对于NIO的学习也是一直半解,最近在网上查阅了很多资料,发现有很多概念是需要反复理解的,有的时候甚至当时理解了,但一段时间后又忘记了,所以决定自 ...