• 函数名的应用,闭包,迭代器


    一. 函数名的应用

    1. 函数名的内存地址

    def f():
        pass
    print(f)  #结果为函数f的内存地址  <function f at 0x000001CC079097B8>

    2. 赋值

    def f():
        print('hello,world')
    a = f  #把函数赋值给a
    a()  #函数调用,结果为 hello,world

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

    def f1():
        return 'hello'
    def f2():
        return 'world'
    def f3():
        return 'better'
    def f4():
        return 'python'
    lst1 = [f1, f2, f3, f4]
    lst2 = [f1(), f2(), f3(), f4()]
    print(lst1)  #四个函数的内存地址列表
    print(lst2)  #四个函数的返回值列表 ['hello', 'world', 'better', 'python']

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

    def f(fn):
        fn()
    def g():
        print('今天吃饭了吗')
    f(g)  #把函数名作为参数,传给另一个函数

    5. 函数名可以当返回值

    def f1():
        print('hello,world')
        return f2
    def f2():
        print('snowdreams')
    
    a = f1()  #把函数f1的返回值f2赋值给a
    a()  #a(),其实就是调用函数f2 ,结果为 snowdreams

    二. 闭包

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

    def f1():
        a = 10
        def f2():
            print(a)  #引用了外层函数f1的局部变量a,是闭包
        f2()
    f1()  #10

       可以使用__closure__来检测函数是否是闭包.使用函数名.__closure__返回cell就是闭包,返回None就不是闭包.

    def f1():
        a = 10
        print(f1.__closure__)  #结果为 None 不是闭包
        def f2():
            print(a)  #引用了外层函数f1的局部变量a
        f2()
        print(f2.__closure__)  #判断是否是闭包结果是 (<cell at 0x00000196FC15C7F8: int object at 0x00007FF9E778D540>,) 是闭包
    f1()  #10

      闭包的好处: 1. 安全 ,只能在函数内部才可以更改值  2.  常驻内存,提高效率

    三. 迭代器

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

      可以用dir()查看类中所有定义好的方法,含有__iter__,那么这个类的对象就是一个可迭代对象.

    li = [1,2,3,4,5,6,7]
    print(dir(li))  #含有__iter__, 表示li是可迭代的 
    
    # ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', 
    #  '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__',
    #  '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', 
    #  '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', 
    #  '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 
    #  'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

      可以进行for循环的东西都有__iter__,包括range也有. 还可以通过isinstence()函数来查 看一个对象是什么类型的. 

      __iter__是获取到对象的迭代器. 使用迭代器中的__next__()来获取到一个迭代器中的元素. isinstence(对象, 类型) 判断xx对象是否是xxx类型的.

    li = [1,2,3,4,5,6,7]
    it = li.__iter__()  #使用__iter__来获取列表li的迭代器
    from collections import Iterable
    from collections import Iterator
    print(isinstance(li,Iterable))  #判断列表li是否可迭代 结果为 True
    print(isinstance(li,Iterator))  #判断列表li是否是迭代器 结果为 False
    print(isinstance(it,Iterable))  #判断it是否可迭代 结果为 True
    print(isinstance(it,Iterator))  #判断it是否是迭代器 结果为 True
    lst = [1, 2, 3, 4,]
    it = lst.__iter__()  #获取lst的迭代器
    print(it.__next__())  #1
    print(it.__next__())  #2
    print(it.__next__())  #3
    print(it.__next__())  #4
    # print(it.__next__())  #取完了,没有值可取,会报错
    #模拟for循环
    lst = [1,2,3,4,5]
    it = lst.__iter__()
    while True:
        try:
            num = it.__next__()
            print(num)
        except StopIteration:  #若出现StopIteration错误,就break.
            break

      总结:

      Iterable: 可迭代对象. 内部包含__iter__()函数       

      Iterator: 迭代器. 内部包含__iter__() 同时包含__next__().        

      迭代器的特点: 1. 节省内存.      2. 惰性机制     3. 不能反复, 只能向下执行.

    无限的我,现在才开始绽放,从东边的第一缕阳光到西边的尽头
  • 相关阅读:
    PHP如何获取内网IP
    开源的世界并不纯净
    在linux下玩上了第一人称射击
    终于,在linux下上网了
    我的理想
    vista是什么
    我傻了一阵子
    又是大端小端!!!
    谈谈最近的编程状态
    如何快速发布你的C++Builder程序
  • 原文地址:https://www.cnblogs.com/huangqihui/p/9330024.html
Copyright © 2020-2023  润新知