迭代器相关
Posted lingcai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了迭代器相关相关的知识,希望对你有一定的参考价值。
1 函数名的使用以及第一类对象
函数名就是一个变量,命名规范与变量一致(8条)但它是一个特殊的变量,与()配合可以调用函数的变量.
<1>函数名的内存地址.
def func(): print("haha") print(func) #答案<function func at 0x0000021406756048>是函数名func的内存地址
<2>函数名可以赋值给其它变量
def func(): print("haha") print(func) #打印变量func内存地址 ret=func #把函数名func赋值给变量ret ret() #ret()相当于func(),即调用函数func
<3>函数名可以当做容器类的元素,即可以当做列表中的元素进行储存
def func(): pass def func_1(): pass lst=[func,func1] for i in lst: i()
<4>可以作为参数传递给函数
def func(): pass def proxy(fn): fn() #调用fn函数,即如果func传递进来以后就调用func函数. proxy(func) #调用proxy函数,把func传递到fn位置
<5>可以作为函数的返回值.
def outer(): pass def inner(): pass return inner #返回 inner outer()() #第一个括号调用outer函数,返回inner,第二个括号相当于inner(),即调用inner函数.
2闭包
闭包就是内层函数对外层函数(非全局)变量的引用.也就是说在内层函数中访问外层函数的局部变量.
作用:1可以保护你的变量不受侵害
2可以让一个变量常驻
完整的闭包函数格式 def func(): a=12 def inner(): print(a) return inner
我们可以用__closure__来检测函数是不是闭包.返回cell就是闭包,返回None就不是闭包.
def func(): a=12 def inner(): print(a) return inner print(func().__closure__)# 结果(<cell at 0x0000016801C67588: int object at 0x0000000050496D70>,)
好处:原来我们说过,如果在外层函数中访问过内层函数,那么内层函数将会被销毁.在闭包中如果内层函数被销毁,将不能正常执行.所以Python中规定,如果你在内部函数中访问了外层函数中的变量,那么这个变量将不会被销毁,常驻内存中.也就是说,使用闭包,可以保证外层函数中的变量在内存中常驻.
极其简易爬虫代码:
from urllib.request import urlopen def but(): content=urlopen("http://www.xiaohua100.cn/").read() # 获取网页内容 def get_content(): return content return get_content ret = but() #这个时候 执行but()就开始执行校花100的内容了,后面再用到这里的内容就不需要执行非常繁琐的网络连接 el = ret() #获取内容 print(el) el1 =ret() # 再次获取内容 print(el1)
3迭代器
<1>可迭代对象:str list tuple dict set.因为它们遵守了可迭代协议,所以为可迭代对象.
<2>如何查询是不是可迭代(dir),寻找__iter__ 如果能找到. 那么这个类的对象就是?一个可迭代对象.可以执行for循环.
print(dir(str)) #查看str(字符串)可以执行哪些操作,方法#[‘__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‘]
我们还可以通过isinstance函数来查看一个对象是什么数据类型的.
l = [1,2,3] l1=l.__iter__() # 获取l的迭代器 from collections import Iterable from collections import Iterator print(isinstance(l,Iterable)) # True 是否可迭代 print(isinstance(l,Iterator)) # False 是否是迭代器 print(isinstance(l1,Iterable)) # True print(isinstance(l1,Iterator)) # True
<3>可迭代对象:Iterable 里面有__iter__()
迭代器:iterator 里面有 __iter__()和__next__()
迭代器特点:1只能向前2惰性机制3节省内存
<4>for循环
内部机制: 1使用__iter__获取迭代器
2使用while循环与__next__来获取数据
3处理异常 try *** except StopIteration
数据结构 : it=xx.__iter__() while 1: try: data=it.__next__() except Stopiteration: break
例子:
l=[1,2,3] l1=l.__iter__() while 1: try: data=l1.__next__() print(data) except StopIteration: break # 结果1 2 3
我们可以把要迭代的内容当成?子弹. 然后呢. 获取到迭代器__iter__(), 就把?子弹都装在弹夹 中. 然后发射就是__next__()把每?一个?子弹(元素)打出来. 也就是说, for循环的时候. ?一开始的 时候是__iter__()来获取迭代器. 后?面每次获取元素都是通过__next__()来完成的. 当程序遇到 StopIteration将结束循环.
我们可以把要迭代的内容当成子弹,然后,获取到迭代器__iter__()相当于把子弹装在弹夹中,__next__()就是把每一子弹打出来,for循环的时候也是一开始__iter__()获取迭代器,后面循环出的每一个元素都是通过__next__()来完成的,程序遇到StopIteration结束循环.
以上是关于迭代器相关的主要内容,如果未能解决你的问题,请参考以下文章