zoukankan      html  css  js  c++  java
  • day 10 函数名的运用,闭包,迭代器

    函数名的本质

    函数名本质上就是函数的内存地址

    函数名的五种运用:

     1、函数名是一个变量

    def func():
        print(666)
    print(func)    # 函数的内存地址 <function func at 0x000002B6D2559AE8>

    2、函数名可以当做变量赋值

    def func():
        print(666)
    f1 = func
    f2 = f1
    f2()                

    3、函数名可以当做容器类数据类型的元素

    def func1():
        print(111)
    def func2():
        print(222)
    def func3():
        print(333)
    l1 = [func1, func2 ,func3]
    for i in l1:
        i()

    4、函数名可以当做函数的参数

    def func(x):   #  x  == func1
        x()
        print('in func')
    def func1():
        print('in func1')
    func(func1)

    5、函数名可以当做函数的返回值

    def func(x):  # x ---> func1
        return x  # func1
    
    def func1():
        print('in func1')
    
    ret = func(func1)  #  ret = func1
    ret()     # func1()
    func(func1)()  # x() == func1()

    满足3,4,5 函数名也称为第一类对象

    闭包:

    什么是闭包:

    def func():
        name = 666
        print(111)
        def func1():
            print(name)  # 这就是闭包, 内层函数对外层函数(非全局)变量的引用
        func1()
    func()
    1,内层函数对外层函数(非全局)变量的引用。
    2,闭包只存在于内层函数中。
    3,函数都要逐层返回,最终返回给最外层函数。
    def func():
        name = 'alex'
        def inner():
            print(name)
        return inner           
    f = func()    #  f = inner
    f()

    闭包的判断

    f.__closure__[0].cell_contents   闭包引用的外部变量
    def func():
        name = 'alex'
        age = 19
        def inner():
            print(name)
            print(age)
        return inner
    f = func()         # 定义f,因为f是闭包
    # 获取闭包引用的外层变量,如果不是闭包则报错
    print(f.__closure__[0].cell_contents)  #固定用法  19
    print(f.__closure__[1].cell_contents)  # alex

    闭包有什么用?

    闭包:解释器执行程序时,如果遇到函数,随着函数的结束而关闭临时名称空间,但是!!!如果遇到闭包,有一个机制:那么闭包的空间不会随着函数的结束而关闭。

    def wrapper(step):
        num =1
        def inner():
            nonlocal num
            num += step
            print(num)     # 输出 4   7   10  13  16
        return inner
    f = wrapper(3)
    j = 0
    while j < 5:
        f()
        j += 1

    闭包就是在内存中开一个空间,常贮存一些内容,以便后续程序调用
    闭包的应用:
    1、装饰器
    2、爬虫

    迭代对象:
    iterable: 可迭代对象
    内部含有__iter__方法的就是可迭代对象,遵循可迭代协议
    s1 = 'barry'
    l1 = [1, 2, 3]
    print('__iter__' in dir(s1))  # True  是可迭代对象

    可迭代对象不能直接取值(含索引的迭代对象除外) ,需要转换成迭代器才能取值

    迭代器

    迭代器:内部含有'__iter__'并且含有'__next__'方法的就是迭代器,遵循迭代器协议。

    可迭代对象转换成迭代器:

      可迭代对象.__iter__()

      obj = iter(可迭代对象)

    判断一个一个对象是否是迭代器(含iter,next)或迭代对象

     方法一:  看__iter__ , __next__  在不在dir() 里面

    s1 = 'abcdefg'
    obj = iter(s1)    # 将s1转换成迭代器
    print('__iter__' in dir(s1))   # True
    print('__iter__' in dir(obj))  # True
    print('__iter__' in dir(s1) and '__next__' in dir(s1))  # False
    print('__iter__' in dir(obj) and '__next__' in dir(obj)) # True
    方法二:   isinstance(obj, Iterable/Iterator)
    s1 = 'abcdefg'
    obj = iter(s1)    # 将s1转换成迭代器
    from collections import Iterable   # 迭代对象
    from collections import Iterator   # 迭代器
    print(isinstance(obj,Iterator))  # 判断obj是否为迭代器     True
    print(isinstance(obj,Iterable))  # 判断obj是否为可迭代对象 True
    print(isinstance(s1,Iterator))   # 判断obj是否为迭代器     False
    print(isinstance(s1,Iterable))   # 判断obj是否为可迭代对象 True
    
    

    迭代器取值

    s2 = [1, 2, 3]
    obj = iter(s2)
    print(obj.__next__())    # 方法一
    print(next(obj))            # 方法二
    type() isinstance()区别?

    # type()只是判断该对象的数据类型
    # isinstance()不仅可以判断该对象的数据类型,而且可以判断其他很多

    迭代器的作用:
    1、节省内存
    2、惰性机制 (netx())一下,出一个值
    3、一条路走到黑,不走回头路

    While循环模拟for循环机制
    l1 = [i for i in range(10)]
    obj = iter(l1)
    while 1:
        try:     # 试一试,如果报错就执行下面的命令
            print(next(obj))
        except StopIteration:  
            break



     

      

  • 相关阅读:
    SecureCRT_FX8.0完整版
    bridge
    Quartz 框架 教程(中文版)2.2.x
    Quartz教程五:SimpleTrigger
    Quartz教程四:Trigger
    Quartz教程三:Job与JobDetail介绍
    Quartz教程二:API,Job和Trigger
    Quartz教程一:使用quartz
    Quartz教程:快速入门
    Kubernetes 1.5.3 部署
  • 原文地址:https://www.cnblogs.com/echo2019/p/10209127.html
Copyright © 2011-2022 走看看