函数3—迭代器

一、函数名的应用,第一类对象

  函数名可以像变量一样进行使用

  1、赋值

#函数名的内存地址:
def func():
    print("紫薇")
print(func)
#结果:
<function func at 0x0000017923B92F28>

#函数名赋值给其他变量
def func():
    print("紫薇")
print(func)   #函数的内存地址
a = func   #把函数当成一个变量赋值给另一个元素
a()   #函数调用func()
#结果:
<function func at 0x00000272341D2F28>
紫薇

 

  2、作为容器类的元素

#函数名作为容器类的元素
def func1():
    print("紫薇")
def func2():
    print("紫薇")
def func3():
    print("紫薇")
def func4():
    print("紫薇")
lis = [func1,func2,func3,func4]
for el in lis:
    el()

 

  3、作为参数

函数名当作函数的参数
def func():
    print("我想紫薇了!")
def func2(fn):
    print("我也想紫薇!")
    fn()   #执行传递过来的fn
    print("我很想紫薇!")
func2(func)  #把函数func当成参数传递给func2的参数fn
#结果:
我也想紫薇!
我想紫薇了!
我很想紫薇!

 

  4、作为返回值

#函数名作为函数的返回值
def func():
    print("我是紫薇!")
    def func2():
        print("我也是紫薇!")
    print("我才是紫薇!")
    return func2
fn = func()  #执行函数func,函数func返回的是函数func2,这时的fn指向的就是上面函数
fn()   #执行上面返回的函数
#结果:
我是紫薇!
我才是紫薇!
我也是紫薇!

 

二、闭包:内层函数对外层函数(非全局)的变量的引用的 作用。

  内部函数访问外部函数的局部变量

def func1():
    name = "紫薇"
    def func2():
        print(name)  #闭包
    func2()
func1()

#结果:
紫薇

---------------------------------------------------------

可以使用__closure__来检测函数是否时闭包。使用函数__closure__返回cell就是闭包,返回None就不是闭包
def func1():
    name = "紫薇"
    def func2():
        print(name)
    func2()
    print(func2.__closure__)
func1()
#结果:
紫薇
(<cell at 0x0000018F1A737498: str object at 0x0000018F1A732D40>,)


#如何在函数外边调用内部函数
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规定. 如果你在内部函数中访问了外层函数中的变量. 那么这个变量将不会消亡. 将会常驻在内存中. 也就是说. 使⽤闭包, 可以保证外层函数中的变量在内存中常驻

  好处:

    1、安全

    2、常驻内存,提高效率

  实例:爬虫实例

from urllib.request import urlopen
def but():
    content = urlopen("http://www.youku.com/").read()
    def get_content():
        return content
    return get_content
fn = but()
content = fn()
print(content)
content2 = fn()
print(content2)

 

三、迭代器

  1、可迭代对象(Iterable):内部包含__iter__().

#对的
s= "abcd"
for el in s:
    print(el)

#错的
for el in 123:
    print(el)

报错:TypeError: 'int' object is not iterable(整数类型对象 是不可迭代的. iterable表⽰可迭代的. 表⽰可迭代协议. )

  dir()函数:查看类中定义好的所有方法。

s = "我是张无忌"
print(dir(s))  #打印对象中声明的方法和函数
print(dir(str)) #打印类中声明的方法和函数
#在打印结果中,找到__iter__的话,那么这个类的对象就是一个可
迭代对象

#字符串中可以找到__iter__。在list,tuple,dict,set中查看:
print(dir(tuple))
print(dir(list))
print(dir(open("alex.txt"))) #文件对象
print(dir(set))
print(dir(dict))
#能进行for循环的东西都有__iter__函数,包括range也有

  isinstance()函数:isinstance(对象,类型)判断xxx对象是否是xxx类型的

lis = [1,2,3]
lis_l = lis.__iter__()
from collections import Iterable  #可迭代的
from collections import Iterator  #迭代器
# ininstance(对象,类型),#判断xxx对象是否是xxx类型的
print(isinstance(lis,Iterable))  #结果是True
print(isinstance(lis,Iterator))  #结果是False
print(isinstance(lis_l,Iterable))  #结果是True  判断是否是可迭代的,迭代器一定是可迭代的
print(isinstance(lis_l,Iterator))  #结果是True  迭代器里面一定有__next__(),__iter__()
print("__iter__" in dir(lis))  #确定是一个可迭代的  结果是Ture
print("__next__" in dir(lis))  #确定不是一个迭代器  结果是False

f = open("文件.txt",mode="r",encoding="utf-8")
print(isinstance(f,Iterable))
print(isinstance(f,Iterator))

 

  2、迭代器(Iterator):内部包含__iter__() 、__next__()

s = "大明湖畔夏雨荷"
s1 = s.__iter__()   #获取迭代器
print(s1.__next__())  #使用迭代器进行迭代,获取一个元素
print(s1.__next__())
print(s1.__next__())
print(s1.__next__())
print(s1.__next__())
print(s1.__next__())
print(s1.__next__())
print(s1.__next__())  #报错:StopIteration

  

for循环机制:

for el in [1,2,3]:
    print(el)

使用while循环+迭代器来模拟for循环(重点掌握):

lis = [1,2,3]
li_iter = lis.__iter__()
while True:
    try:
        el = li_iter.__next__()
        print(el)
    except StopIteration:
        break

#我们可以把要迭代的内容当成⼦弹. 然后呢. 获取到迭代器__iter__(), 就把⼦子弹都装在弹夹 中. 
然后发射就是__next__()把每⼀个⼦弹(元素)打出来. 也就是说, for循环的时候. ⼀开始的时候
是__iter__()来获取迭代器. 后⾯每次获取元素都是通过__next__()来完成的. 当程序遇到
StopIteration将结束循环

  

  3、可迭代数据类型:str、list、tuple、set、dict

  4、迭代器数据类型:f(文件)、range

  5、迭代器的特点:

     1、节省内存

     2、惰性机制

     3、不能返回,只能向下执行

转载于:https://www.cnblogs.com/LW-5208/articles/9325856.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值