• python 闭包和迭代器


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

     (1)  数名可以赋值给其他变量
    def chi():
        print("吃月饼")
    fn=chi  # 函数名可以进行赋值
    a=10
    b=a
    chi()
    fn()    # 函数名可以像变量名一样进行使用

    def func1(): print(
    "我是一个单纯的函数") def func2(abc): abc() print("我是func2,",abc) func2(func1) #func1是一个内存地址,函数名可以像变量一样进行参数传递

    例子二:
    def func():
        print("呵呵")
    print(func)
    a = func # 把函数当成一个变量赋值给另一个变量
    a() # 函数调用 func()
    
    

    pass

    def outer():
        # print('我i')
        def inner():
            print("我是里面")
        return inner
    outer()()  #表示的是执行 它可以执行里面的函数
    
    ret=outer()    #outer的结果是inner
    ret()      #执行的是inner函数

    (2) 函数可以当作容器类元素

    def chi():
        print("吃饭")
    def he():
        print("喝饮料")
    def du():
        print("赌是不好的")
    def chou():
        print("少抽点烟")
    
    lst = [chi, he, du, chou]
    for el in lst:
        el() #表示执行

    核心业务逻辑

    def panpan():
    #     print("我是潘潘. 我喜欢毒丈夫 ")
    #
    # def xiaoping():
    #     print("我是小萍萍. 我喜欢毒丈夫 ")
    #
    # def xiaohua():
    #     print("我是小花花. 我喜欢毒丈夫 ")
    #
    # def daguanren():
    #     print("大官人喜欢xxxx")
    #
    # def wangpo(nv, nan): # 核心业务逻辑
    #     nv()
    #     nan()
    #
    # wangpo(xiaohua, daguanren) # 王婆代理了大官人和潘潘

    (3) 函数名 可以当作函数的参数

    def func():
        print("吃了么")
    def func2(fn):
        print("我是func2")
        fn() # 执⾏行行传递过来的fn
    # print("我是func2")
    func2(func) # 把函数func当成参数传递给func2的参数fn.

    (4)函数名可以作为函数的返回值

    def func_1():
        print("这⾥是函数1")
        def func_2():
            print("这里是函数2")
        print("这⾥是函数1")
        return func_2
    fn = func_1() # 执⾏行行函数1. 函数1返回的是函数2, 这时fn指向的就是上⾯面函数2
    fn() # 执⾏行行上⾯面返回的函数

    二 闭包 (函数的嵌套. 返回函数名)

    写法:再外层函数中声明一个变量,在内层函数中使用或者返回这个变量,这个结构叫做闭包

    基本写法
                def outer():
                    a = 10
                    def inner():
                        return a
                    return inner

    简单例子 看看闭包作用 其一:  可以保护我们的变量

     def func():
    #     a = 10
    #     print(a)
    # func()
    # print(a) # 在外面你是访问不到局部变量的, 局部变量是安全的
    
    
    # 全局变量可能会被修改, 全局变量是不安全的. 可能会被其他函数所更改
    # a = 10
    # def func():
    #     global a
    #     a = 20
    #     print(a)
    # func()
    # print(a)

    (2) 可以让一个变量常驻内存:

    def outer():
    #     a = 10 # 常驻内存
    #     def inner():
    #         print(a) # 在内部使用的外面的变量
    #     return inner # 返回了内部函数
     ret是inner的地址. ret就是inner
    ret=outer()
    ret() # 这里执行的是inner()

           print("哈哈")
    # #    print("哈哈")
    # #    print("哈哈")

           ret() # inner的执行时间是不确定的

          print("哈哈")
    # #   print("哈哈")
    # #   print("哈哈")
    # #   ret() # inner的执行时间是不确定的


    print(ret.__closure__) # 有东西, 就是闭包. None就不是闭包 j查看是不是闭包

    #     闭包的应用.保护变量, 常驻内存

    检查是否为闭包
    def func1(): name
    = "alex" def func2(): print(name) # 闭包 func2() print(func2.__closure__) # (<cell at 0x10c2e20a8: str object at 0x10c3fc650>,) func1()

    小问题 ;如何在函数外部调用内部函数

    def outer():
    name = "alex"
    # 内部函数
    def inner():
    print(name)
    return inner
    fn = outer() # 访问外部函数, 获取到内部函数的函数地址
    fn() # 访问内部函数

    小拓展:j简单爬网站 (具体是常驻内存的应用 , 目的为下次打开更快 无序加载,主要对象为一些刷新率低的网站,

    from urllib.request import urlopen
    
    def func():
        # 闭包. content会常驻内存
        content = urlopen("http://www.xiaohuar.com/").read()
        def inner():
            return content
        return inner
    
    print("加载中...")
    g = func() # 网络请求
    print("加载完毕")
    print(g())
    print(g())
    print(g())

    三 迭代器   ( 

    特点:
    1. 节省内存()
    2. 惰性机制(只有执行__next__()才会取值)
    3. 只能向前. 不能反复

    可跌代对象:

    str, list, tuple, dict, set. open() .range() 那为什么我们可以称他们为可迭代对象呢? 因为他们都遵循了可
    迭代协议.

    dir() 可以查看某数据类型中可以执行的方法

    例子1

    s = "alex"
    # print(dir(s)) # 在字符串中发现了__iter__. 没有__next__
    # a = 123
    # print(dir(a)) # 在int中没有__iter__ 没有__next__

    例子2

    lst = [1, 2, 3,]

    lst = [1, 2, 3,]
    # print(dir(lst)) # 在list中也有__iter__

    例子3

    a=123
    # for i in 123:
    print(dir(a)) #"int"object is not iterable (整数类型不可迭代)也没有__iter__

    小结论: 所有包含了__iter__的东西都可以使用for循环,都可以进行迭代.

    for 循环机制:

    lst = [1, 2, 3, 4, 5, 6]
    #
    it = lst.__iter__() # iterator 迭代器
    while 1:
    try: # 表示放手去干的意思 不然打印出来会有小瑕疵

    print(it.__next__())
    except StopIteration: #出了事我兜着 不然打印出来会有小瑕疵
    print("结束了")
    break

    对比下:

    lst = [1, 2, 3, 4, 5]
    
    for el in lst:
        print(el)
    else:
        print("结束了")  两个结果一样  

    (2)  迭代器给所有数据提供了一种统一的遍历方式(可跌代协议) ,Iterable,__iter__()


    看是否是可跌代的 两种情况:

    lst=[1,2,3,4,5] print("__iter__"in dir(lst)) # trut print("__next__"in dir(lst)) false # 换没执行 所以没有 # it = lst.__iter__() # 执行 # print("__iter__" in dir(it)) # ture 迭代器里面是有__iter__的. 迭代器一定是可迭代的 # print("__next__" in dir(it)) # ture

    for el in it: # 迭代器可以使用for循环

    # print(el)

     小结  :Iterable: 可迭代对象. 里面包含了__iter__(),可以使用for循环

             Iterator: 迭代器. 里面包含了__iter__() 和 __next__(), 也可以使用for循环

    看是否是可跌代的还有看是不是迭代器  两种情况:

    from
    collections import Iterable # 可迭代的 from collections import Iterator # 迭代器 lst = ["周润发","麻花藤","刘伟"] print(isinstance(lst, Iterable)) # instance 实例, 对象 print(isinstance(lst, Iterator)) #instance 实例 对象 it = lst.__iter__() print(isinstance(it, Iterable)) # instance 实例, 对象 print(isinstance(it, Iterator)) # instance 实例, 对象
    只能向前不能 反复

    lst = [1,2,3] it = lst.__iter__() print(it.__next__()) print(it.__next__()) print(it.__next__()) #重新拿一个迭代器 执行完第一个就没了 t = lst.__iter__() print(it.__next__()) print(it.__next__()) print(it.__next__())

    我们可以把要迭代的内容当成子弹. 然后呢. 获取到迭代器__iter__(), 就把子弹都装在弹夹
    中. 然后发射就是__next__()把每一个⼦子弹(元素)打出来. 也就是说, for循环的时候. ⼀一开始的
    时候是__iter__()来获取迭代器. 后⾯面每次获取元素都是通过__next__()来完成的. 当程序遇到
    StopIteration将结束循环.

  • 相关阅读:
    直击微软第九频道著名主持Robert Green 对话一站式示例代码库大老板梁梅女士
    微软发布中文版一站式示例代码浏览器
    每日一例,练就编程高手
    微软发布Visual Studio 2012 示例代码浏览器
    微软发布Sample Browser for Windows 8版:5000示例代码,"触手可及"
    arthas使用总结
    前端如何生成二维码
    golang的helloworld以及nonmain package的troubleshooting
    监控文件的网页工具
    postfix + courierimap + squirrelMail 邮件服务器
  • 原文地址:https://www.cnblogs.com/systemsystem/p/9665165.html
Copyright © 2020-2023  润新知