• day12


    1. 函数名的应用以及第一类对象

    # 函数名是一个变量, 但它是⼀个特殊的变量, 与括号配合可以执⾏函数的变量. 
    
    # 1. 函数名的内存地址
        def func():
            print("呵呵")
        print(func)  # <function func at 0x0000022C99B3D1E0>
    
    # 2. 函数名可以赋值给其他变量
        def func():
            print("你吃了吗")
    
        print(func)  # 打印func的内存地址
        a = func    # 把函数当成⼀个变量赋值给另⼀个变量
        print(a)  # 打印a,也是func的内存地址
        func()  # 函数的调用
        a()  # 也是函数的调用
    
    # 3. 函数名可以当做容器类的元素
        (1) 首先看整数当做列表里的元素:
        例:
            a = 8
            b = 7
            c = 1
            d = 3
        
            lst = [a, b, c, d]
            print(lst)
    
        (2) 再看函数当做列表的元素
            def f1():
                print("我是马化腾")
            def f2():
                print("我是马云")
            def f3():
                print("我是马赛克")
            def f4():
                print("我是马忠军")
        
        例1:
            lst = [f1, f2, f3, f4]
            for el in lst:
                el()
    
        例2:
            lst = [f1(), f2(), f3(), f4()]  # 这时list是4个None, 因为没有return默认返回None
            print(lst)
    
    # 4. 函数名可以当做函数的参数
        例1:
            def func(fn):
                fn()
        
            def gn():
                print("我是火锅, 刚才有人要吃我")
            func(gn)  # 把函数gn当成实参传给func的形参fn
    
        例2:
            def func():
                print("吃了么")
        
            def func2(fn):
                print("我是func2")
                fn()  # 执⾏传递过来的fn
                print("我是func2")
    
            func2(func)  # 把函数func当成参数传递给func2的参数fn.
    
    # 5. 函数名可以作为函数的返回值
        例1:
            def func():
                def inner():
                    print("火锅不让吃了. 吃了上火")
                return inner
            ret = func()  # 这里func()执行过后获取到的是inner函数
            ret()  # 这里是让inner函数执行
    
        例2:
            def func_1():
                print("这⾥是函数1")
                def func_2():
                    print("这⾥是函数2")
                print("这⾥是函数1")
                return func_2
    
            fn = func_1()  # 执⾏函数1. 函数1返回的是函数2, 这时fn指向的就是上⾯函数2
            fn()  # 执⾏上⾯返回的函数func2

      综上: 函数就是一个变量

     2. 闭包

    # 1. 什么是闭包? 闭包就是内层函数, 对外层函数(非全局)的变量的引⽤. 叫闭包.
        例:
            def func():
                name = 'alex'   # 常驻内存 防止其他程序改变这个变量
                def inner():
                    print(name)   # 在内层函数调用了外层函数的变量,叫闭包. 可以让一个局部变量常驻内存.
                return inner
    
    # 2. __closure__可以来检测函数是否是闭包. 使⽤函数名.__closure__返回cell就 
    是闭包. 返回None就不是闭包
        例:
            def func1():
                name = "alex"
                def func2():
                    print(name)  # 闭包
                    print(func2.__closure__)  # (<cell at ......>)
                func2()
            func1()
    
    # 3. 在函数外边调⽤内部函数
        (1) 函数里套了一层函数
            def outer():
                name = "alex"
                # 内部函数
                def inner():
                    print(name)
                return inner
            fn = outer() # 访问外部函数, 获取到内部函数的函数地址
            fn()  # 访问内部函数
    
        (2) 函数多层嵌套
            def func1():
                def func2():
                    def func3():
                        print("嘿嘿")
                    return func3
                return func2
            
            func1()()()
    
        闭包的好处:
                1. 常驻内存
                2. 防止其他程序改变这个变量

     3. 迭代器

    # 1. 可迭代的
      # 对的
      s = "abc"
      for c in s:
        print(c)
    
      # 错的
      for i in 123:
          print(i)  # TypeError: 'int' object is not iterable.(这里iterable表⽰可迭代的. 表⽰可迭代协议.)
    # 2. 可迭代(Iterable)对象: str, list, tuple, dict, set, f ,range.
      # 所有的以上数据类型中都有一个函数__iter__(), 所有包含了__iter__()的数据
        类型都是可迭代的数据类型(Iterable)
    
      # dir()来查看一个对象,数据类型中包含了那些东西.
      # 验证数据类型是否符合可迭代协议. 可以通过dir函数来查看类中定义好的所有⽅法.
          s = "我的哈哈哈"
          print(dir(s))  # 可以打印对象中的⽅法和函数
          print(dir(str))  # 也可以打印类(str类)中声明的⽅法和函数
          他们都有__iter__函数, 是可迭代的(Iterable)
    
          lst = [1, 2, 3]  # list
          print(dir(lst))  # 其中有__iter__函数,是可迭代对象.
          s = "王尼玛"
          # __iter_这个函数是否在他们的的方法中.
          print("__iter__" in dir(s))  # Ture
          print("__iter__" in dir(lst))  # Ture
          print("__iter__" in dir(123))  # False
    # 3. 迭代器
    
    # 迭代器从可迭代对象中开始迭代
        lst = ["皇阿玛", "皇额娘", "容嬷嬷", "紫薇"]
        it = lst.__iter__()  # 获取迭代器
        # 迭代器往外拿元素.__next__()
        print(it.__next__())  # 皇阿玛
        print(it.__next__())  # 皇额娘
        print(it.__next__())  # 容嬷嬷
        print(it.__next__())  # 紫薇
        print(it.__next__())  # 迭代到最后一个元素之后. 再迭代就报错了
    
    # 模拟for循环
        lst = ["皇阿玛", "皇额娘", "容嬷嬷", "紫薇"]
        it = lst.__iter__()  # 这个对象获取他的迭代器
        while 1:
            try:
                name = it.__next__()
                print(name)
            except StopIteration:  # 拿完了
                break
    # 3. 迭代器
    
    # 迭代器从可迭代对象中开始迭代
        lst = ["皇阿玛", "皇额娘", "容嬷嬷", "紫薇"]
        it = lst.__iter__()  # 获取迭代器
        # 迭代器往外拿元素.__next__()
        print(it.__next__())  # 皇阿玛
        print(it.__next__())  # 皇额娘
        print(it.__next__())  # 容嬷嬷
        print(it.__next__())  # 紫薇
        print(it.__next__())  # 迭代到最后一个元素之后. 再迭代就报错了
    
    # 模拟for循环
        lst = ["皇阿玛", "皇额娘", "容嬷嬷", "紫薇"]
        it = lst.__iter__()  # 这个对象获取他的迭代器
        while 1:
            try:
                name = it.__next__()
                print(name)
            except StopIteration:  # 拿完了
                break
    # 4. isinstance(对象, 类型)  判断xx对象是否是xxx类型
    
        # 用 Iterable中isinstance方法判断一个对象是否可以迭代时,要先导入包
        from collections.abc import Iterator  # 迭代器
        from collections.abc import Iterable  # 可迭代的
        
        lst = [1, 2, 3]
        # 判断列表是否是可迭代的,是否是迭代器
        print(isinstance(lst, Iterable))  # Ture
        print(isinstance(lst, Iterator))  # False
    
        # 判断迭代器是否是可迭代的,是是否是迭代器
        it = lst.__iter__()
        print(isinstance(it, Iterable))  # True 判断是否是可迭代的 迭代器一定是可迭代的
        print(isinstance(it, Iterator))  # True 迭代器里面一定有__next__(), __iter__()
    
        # 用__iter__, __next__ 判断是否可迭代,是否为迭代器
        print("__iter__" in dir(lst))  # True (确定是一个可迭代的)
        print("__next__" in dir(lst))  # False (确定不是一个迭代器)
    # 5. f(文件句柄)是迭代器
        # 用isinstance之前先导入包
        from collections.abc import Iterator
        from collections.abc import Iterable
    
      # 文件句柄是一个迭代器
        f = open("01 课程大纲", mode="r", encoding="utf-8")
        print(isinstance(f, Iterable))  # Ture
        print(isinstance(f, Iterator))  # Ture
        总结:
            可迭代对象(Iterale): str, list, tuple, set, dict
            迭代器(Iterator): f, range
            可迭代对象(Iterale): 内部包含__iter__().
            迭代器(Iterator): 内部含有__iter__(), __next__()

      注意: 可迭代的不一定是迭代器, 但迭代器一定是可以迭代的. 迭代器的特点:
    1. 省内存 2. 惰性机制 3. 不能反复, 只能向下执⾏.
  • 相关阅读:
    前端性能优化
    web缓存
    js实现数组去重并且显示重复的元素和索引值
    前端面试简单整理
    js记录重复字母的个数
    js数组快速排序
    sql数据库链接
    w3cschool -css
    w3cschool -html
    A*算法在栅格地图上的路径搜索(python实现)
  • 原文地址:https://www.cnblogs.com/kangqi452/p/11305723.html
Copyright © 2020-2023  润新知