zoukankan      html  css  js  c++  java
  • 函数第一类对象,闭包,迭代器

    一,函数名的运用:第一类对象

    函数名是一个变量,但是一个特殊的变量,与括号配合可以执行函数的变量.

    1.直接打印函数名就是个内存地址:

    def func():
        print('哈哈')
    print(func)
    结果:<function func at 0x0000000000864488>

    2.函数名可以赋值给其他变量

    def func():
        print('哈哈')
    ret = func  #把函数当成一个变量,赋值给另一个变量
    ret()  #函数调用func()

    3.函数名可以当做容器类的元素:

    def func():
        print('哈哈')
    def func1():
        print('呵呵')
    def func2():
        print('嘿嘿')
    def func3():
        print('嘻嘻')
    lst = [func,func1,func2,func3]
    for i in lst:
        i()
    结果: 哈哈
         呵呵
         嘿嘿
         嘻嘻            

    4,函数名可以当做函数的参数:

    def func():
        print('哈哈')
    def func1(fn): #func传递给fn
        print('呵呵')
        fn() # fn()变成了func() 所以在这里执行func()函数
        print('嘻嘻')
    func1(func)

    5.函数名可以作为函数的返回值

    def func():
        print('哈哈')
        def func1():
            print('嘿嘿')
        print('呵呵')
        return func1
    ret = func()  #执行func()函数,打印出'哈哈',这时候ret指向fun1
    ret()#即func1(),执行func1函数

    二.闭包

    闭包就是内层函数对外层函数(非全局)的变量的引用.

    def func():
        name = 'alex'
        def func1():
            print(name)
        func1()
    func()
    结果:alxe

    __closure__检测函数是否是闭包,是返回cell,不是返回None.

    def func():
        name = 'alex'
        def func1():
            print(name)
        func1()
        print(func1.__closure__)
    func()
    结果: alex (
    <cell at 0x000000000121C078: str object at 0x0000000001202848>,)#是闭包

    1.函数外面调用内部函数:

    def func():
        name = 'alex'
        def func1():
            print(name)
        return func1
    ret = func() #访问外部函数,获取内部函数的内存地址
    ret()  #执行内部函数

    2.多层嵌套:

    def func1():
        def func2():
            def func3():
                print('嘿嘿')
            return func3
        return func2
    func1()()()

    闭包的作用:1.安全,不能从函数外部去修改函数内部的变量

         2.让一个变量常驻内存,供后边的程序使用,效率高

    三.迭代器(Iterator)  可迭代对象:(Iterable)

    可迭代对象:str list tuple dict set 文件句柄f .这些被称为可迭代对象,基于可迭代协议..

    1,dir用法: 

    s = '哈哈哈'
    print(dir(s)) #可以打印对象中的方法和函数
    print(dir(str)) #可以打印类中声明的方法和函数

    用dir打印出来的结果如果能找到__iter__,那么这个类的对象就是一个可迭代对象.

    经过dir查找,发现list,tuple,str,dict,set都有__iter__函数,range也有.这些都是可以用for循环的.

    2.isinstence(对象,类型)判断xx对象是什么类型的

    lst = [1,2,3]
    from collections import Iterable
    from collections import Iterator
    print(isinstance(lst,Iterable))  #判断是否是可迭代对象
    print(isinstance(lst,Iterator)   #判断是否是迭代器
    结果:True
        False
    lst = ['皇阿玛','皇后','皇太子']
    it = lst.__iter__() #获取迭代器
    from collections import Iterable
    from collections import Iterator
    print(isinstance(it,Iterable))
    print(isinstance(it,Iterator))
    结果:True
       True

    结论:迭代器一定是可迭代的,但可迭代的不一点是迭代器

    3.判断是否可迭代的方法:

    s = '哈哈哈'
    lst = [1,2,3]
    i = 123
    print('__iter__'in dir(s))   #True
    print('__iter__'in dir(lst)) #True
    print('__iter__'in dir(i))   #False

    4.__next__()  获取迭代器的元素

    lst = ['皇阿玛','皇后','皇太子']
    it = lst.__iter__() #获取迭代器
    print(it.__next__())
    print(it.__next__())
    print(it.__next__())

    注意:如果有第四个print找不到就会报错

    在迭代器中有__next__()和__iter__()函数

    而在可迭代对象中只有__iter__()函数  所以要确定这个可迭代对象是否是迭代器可以看是否有__next__()

    5.

    f = open("01",mode="r", encoding="utf-8")
    from collections import Iterable
    from collections import Iterator
    print(isinstance(f, Iterable))
    print(isinstance(f, Iterator))
    结果:True  #文件句柄既是可迭代对象有事迭代器
       True

    6.使用while循环 +迭代器来模拟for循环

    lst = [1,2,3]
    lst_iter = lst.__iter__()
    while True:
        try:
            it = lst_iter.__next__()
            print(it)
        except StopIteration:
            break

    迭代器特点:

    1.节省内存

    2.惰性机制

    3.不能反复,只能向下执行

  • 相关阅读:
    html5 file 上传文件
    JavaScript数组去重—ES6的两种方式
    音频资源下载
    whistle工具全程入门
    解构赋值
    节流(Throttling)和去抖(Debouncing)详解
    HTML5实现全屏
    Vue.js 子组件的异步加载及其生命周期控制
    6个Async/Await完胜Promise的原因
    Docker容器学习与分享08
  • 原文地址:https://www.cnblogs.com/ITdong-1/p/9325773.html
Copyright © 2011-2022 走看看