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. 不能反复, 只能向下执⾏.

 

转载于:https://www.cnblogs.com/kangqi452/p/11305723.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值