Day11 python基础---函数进阶2、迭代器

一,函数名的本质

函数名的应用:

1.函数名就是函数的内存地址

def func1():
    return

print(func1)

2.函数名可以作为变量

def func1():
    print('hello')
a = func2
b = a
b()

3.函数名可以当作函数的返回值

def func1():
    return func2

def func2():
    print('hello')
a = func1
b = a
b()()

4.函数名可以当作函数的参数

def func1(x):
    x()

def func2():
    print('hello')
a = func1(func2)

5.函数名可以作为容器类数据类型的元素

def func1():
    print('hello-1')
def func2():
    print('hello-2')
def func3():
    print('hello-3')

li = [func1,func2,func3]
for i in li:
    i()

像上面的函数名这种,第一类对象。

第一类对象(first-class object)指
1.可在运行期创建
2.可用作函数参数或返回值
3.可存入变量的实体。

二,globals(),locals()

1.globals():返回全局变量的一个字典

2.locals():返回当前位置 局部变量的字典

def func1():
    a = 3
    b = 5
    print(globals())
    print(locals())
    def func2():
        a = 10
        b = 20
        print(globals())
        print(locals())
    func2()
func1()
print(globals())
print(locals())

三,闭包

闭包:

  内层函数对外层函数的变量(非全局变量)的引用,并且外层函数返回值为内层函数名,这样就形成了闭包

def wraaper():
    name = 'alex'
    def inner():
        print(name)
    print(inner.__closure__)
    inner()
    return inner
wraaper()

闭包作用:

  当程序执行时,遇到了函数执行,他会在内存中开辟一个空间:局部名称空间,如果这个函数内层成了闭包,那么这个局部名称空间就不会随着函数的结束而消失

from urllib.request import urlopen

def index():
    url = "http://www.xiaohua100.cn/index.html"
    def get():
        return urlopen(url).read()
    return get

xiaohua = index()  # get
content = xiaohua()  # get()
content = xiaohua()  # get()
content = xiaohua()  # get()
content = xiaohua()  # get()
content = xiaohua()  # get()
content = xiaohua()  # get()
content = xiaohua()  # get()
content = xiaohua()  # get()
print(content.decode('utf-8'))

四,迭代器

1.可迭代对象

对象内部含有__iter__方法就是可迭代对象

可迭代对象满足可迭代协议

可迭代对象:str,list,dict,tuple,set,range()

#判断一个对象是否是可迭代对象:
#第一个方法
s1 = 'alex'
s2 = {'name':'alex','sex':'man'}
print('__iter__' in dir(s1))
print('__iter__' in dir(s2))

#第二个方法
from collections import Iterable

print(isinstance(s1,Iterable))

2.迭代器:

对象内部含有__iter__方法且含有__next__方法就是迭代器

f  = open('reg',encoding='utf-8')
print('_iter_' in dir(f))    #句柄是迭代器  True
print('_next_' in dir(f))    # False
print('_iter_' in dir(dict)) #字典是可迭代对象不是迭代器  True
print('_next_' in dir(dict))   #True

3.可迭代对象vs迭代器

   可迭代对象不能取值,迭代器是可以取值的

# 可迭代对象 --->(转化成)迭代器
lis = [1, 2, 3]  # 可迭代对象
# ite1 = lis.__iter__()  # 迭代器  <list_iterator object at 0x0000027A183BFFD0>
ite1 = iter(lis)  # 迭代器  <list_iterator object at 0x0000027A183BFFD0>
print(ite1)

#迭代器如何取值?  next一次,取一个值
print(iter1.__next__())
print(iter1.__next__())
print(iter1.__next__())
print(iter1.__next__()) #取完报错

4.总结

   1.可迭代对象不能取值,迭代器是可以取值的。

   2.迭代器非常节省内存

   3.迭代器每次只会去一个值

   4.迭代器是单方向取值的,一条路走到头

    应用场景:

    1.数据量非常大

    2.只取值,不做其他操作时

5. while 循环模拟for循环:迭代器原理

#步骤:
# 1.将可迭代对象转化成迭代器
# 2.调用__next__方法取值
# 3.利用异常处理停止报错

s1 = 'ffshf1jdoiajfkas'
for i in s1:
    print(i)

iter1 = s1.__iter__()

while 1:
    try:
        print(iter1.__next__())
    except StopIteration:
        break

猜你喜欢

转载自www.cnblogs.com/lianyeah/p/9495008.html