• 切记:Python迭代器只可以读取一次,忽略会有意想不到的麻烦。



    【点击此处跳转笔记正文】

    Python 官网https://www.python.org/


    - ###### Free:大咖免费“ 圣经”教程 python 完全自学教程,不仅仅是基础那么简单……

      自学并不是什么神秘的东西 ,一个人一辈子自学的时间总是比在学校学习的时间长,没有老师的时候总是比有老师的时候多。            —— 华罗庚
    等风来,不如追风去……



    切记:Python迭代器iterator
    只可以读取一次
    (不然会有意想不到的麻烦)


    目 录


      我升级迭代我的Color工具,想让她兼容“颜色控制码”和“英文单词颜色描述”。我不想要一个个敲英文“单词->控制码”一一对应的字典键值对,打算用代码生成。这样子我的代码中就不存在字典,字典是在每次加载Color工具时时生成在机器内存中,这样子是不是感觉代码很“高大”。🤪🤪😜😜
      但这代码编写中,遇到了一个bug——当用“|”运算符联接字典时,却始终少一部分内容。(当花费一天一夜的“闲暇”时光理清后才晓得,这是被“一不注意”就会忽略掉的“小问题”。😁😁)
      为能警醒自己,特意记个笔记。也为有幸阅读此笔记的小伙伴,提个醒,别跟我一样白白浪费大好时光。


    回页首

    看似无恙的代码

    
        def __create_dict(self):
            ''' 创建颜色名称字典color dict。'''
            color_names = 'black red green yellow blue magenta cyan white'.split()
            back_color_names = (f"b_{i}" for i in color_names)
    
            fore_colors = dict(zip(color_names, (f"3{i}" for i in range(8))))
            light_fore_colors = dict(zip((f"l_{i}" for i in color_names), (f"9{i}" for i in range(8))))
            other_fore_colors = dict(zip((f"{i}" for i in 'dark inky atramentous flammulated grassy xanthic blove cerulean purple violescent violaceous albicans gray'.split()), (30, 30, 30, 31, 32, 33, 34, 34, 35, 35, 35, 37, 90)))
     
            back_colors = dict(zip(back_color_names, (f"4{i}" for i in range(8))))
            light_back_colors = dict(zip((f"l{i}" for i in back_color_names), (f"10{i}" for i in range(8))))
            other_back_colors = dict(zip((f"b_{i}" for i in 'dark  inky atramentous flammulated grassy xanthic blove cerulean purple violescent violaceous  albicans gray'.split()), (40, 40, 40, 41, 42, 43, 44, 44, 45, 45, 45, 47, 100)))
            
            style = dict(zip((f"s_{i}" for i in 'off_all bright dim incline inclined underline emphasize overstriking inverse blanking strickout normal blank nothing'.split()),(0, 1, 2, 3, 3, 4, 5, 5, 7, 8, 9, 22, 22, 22)))
            # 用Python新版本字典+运算符“|”依次联接前景、背景和特殊效果样式字典。
            return fore_colors | light_fore_colors | other_fore_colors | back_colors | light_back_colors | other_back_colors | style
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

      这段代码看不出啥毛病,但生成的字典,却少了高亮背景色(light_back_colors)那一段。

    代码生成的字典

    {‘black’: ‘30’, ‘red’: ‘31’, ‘green’: ‘32’, ‘yellow’: ‘33’, ‘blue’: ‘34’, ‘magenta’: ‘35’, ‘cyan’: ‘36’, ‘white’: ‘37’, ‘l_black’: ‘90’, ‘l_red’: ‘91’, ‘l_green’: ‘92’, ‘l_yellow’: ‘93’, ‘l_blue’: ‘94’, ‘l_magenta’: ‘95’, ‘l_cyan’: ‘96’, ‘l_white’: ‘97’, ‘dark’: 30, ‘inky’: 30, ‘atramentous’: 30, ‘flammulated’: 31, ‘grassy’: 32, ‘xanthic’: 33, ‘blove’: 34, ‘cerulean’: 34, ‘purple’: 35, ‘violescent’: 35, ‘violaceous’: 35, ‘albicans’: 37, ‘gray’: 90, ‘b_black’: ‘40’, ‘b_red’: ‘41’, ‘b_green’: ‘42’, ‘b_yellow’: ‘43’, ‘b_blue’: ‘44’, ‘b_magenta’: ‘45’, ‘b_cyan’: ‘46’, ‘b_white’: ‘47’, ‘b_dark’: 40, ‘b_inky’: 40, ‘b_atramentous’: 40, ‘b_flammulated’: 41, ‘b_grassy’: 42, ‘b_xanthic’: 43, ‘b_blove’: 44, ‘b_cerulean’: 44, ‘b_purple’: 45, ‘b_violescent’: 45, ‘b_violaceous’: 45, ‘b_albicans’: 47, ‘b_gray’: 100, ‘s_off_all’: 0, ‘s_bright’: 1, ‘s_dim’: 2, ‘s_incline’: 3, ‘s_inclined’: 3, ‘s_underline’: 4, ‘s_emphasize’: 5, ‘s_overstriking’: 5, ‘s_inverse’: 7, ‘s_blanking’: 8, ‘s_strickout’: 9, ‘s_normal’: 22, ‘s_blank’: 22, ‘s_nothing’: 22}


    回页首

    排查nug

      还以为是Python新增字典联接运算符“|”有数量限制,在Python命令行模式下试炼,七八个dict都可以“相加”,也就排除了是“|”运算符引起的bug。无法可想,再次一行行推敲代码,代码肯定是没毛病的。😣那问题出哪儿了?所幸代码不多,一个一个的print() zip()的值。当排查到light_back_colors字典时,zip()的值为’’(什么都没有)!这不应该啊,它跟back_colors字典的zip()用的是同一变量back_color_names啊,back_colors字典都没毛病!print() back_color_names变量,有输出,看起来没毛病!这……😭😭😭
      在打字手累,用上CV的时候,手滑粘了两条print(),结果第二条输出为’’(什么都没有)。

    再次用代码验证

            input(f"\n试炼:\n1. {', '.join(back_color_names)}\n2. {','.join(back_color_names)}")
    
    • 1

    输出

    试炼:
    1. b_black, b_red, b_green, b_yellow, b_blue, b_magenta, b_cyan, b_white
    2.
    
    • 1
    • 2
    • 3

      第二次读取真的什么都没有!为啥会这样子?查看back_color_names变量的类型先。上码:

            input(f"\n试炼:\nback_color_names Type: {self.set_color(type(back_color_names), 91)}\n1. {', '.join(back_color_names)}\n2. {','.join(back_color_names)}")
    
    • 1

    输出截屏图片
    在这里插入图片描述

    输出

    试炼:
    back_color_names Type: <class 'generator'>
    1. b_black, b_red, b_green, b_yellow, b_blue, b_magenta, b_cyan, b_white
    2.
    
    • 1
    • 2
    • 3
    • 4

      在代码中把back_color_names的类型设定为红色,可以清楚的看到,back_color_names变量是generator(发生器)类型。

    generator(发生器)特性截屏图片
    在这里插入图片描述

    generator(发生器)有以下特别:

    • 遵循迭代器(iterator)协议,迭代器协议需要实现__iter__、next接口。
    • 能过多次进入、多次返回,能够暂停函数体中代码的执行。

      可以看出generator(发生器)就是迭代器iterator,当然第二次读取是“什么都没有”了。于此,我这小小的bug终于揪出!🤗但为啥会这样子呢?还得拷问变量back_color_names……


    回页首

    消亡bug

            back_color_names = (f"b_{i}" for i in color_names)
    
    • 1

      原来,back_color_names变量的解析式我是用小括号包裹,就诞生了一个发生器generator。找到根源,问题也就好解决了——将解析式的小括号换成[],就得到一个list类型的back_color_names变量,可以无限次读取了。至此,遇到的小小bug才算彻底消亡!😋

            back_color_names = [f"b_{i}" for i in color_names]
    
    • 1

    得到想要的完整字典了😏

    {‘black’: ‘30’, ‘red’: ‘31’, ‘green’: ‘32’, ‘yellow’: ‘33’, ‘blue’: ‘34’, ‘magenta’: ‘35’, ‘cyan’: ‘36’, ‘white’: ‘37’, ‘l_black’: ‘90’, ‘l_red’: ‘91’, ‘l_green’: ‘92’, ‘l_yellow’: ‘93’, ‘l_blue’: ‘94’, ‘l_magenta’: ‘95’, ‘l_cyan’: ‘96’, ‘l_white’: ‘97’, ‘dark’: 30, ‘inky’: 30, ‘atramentous’: 30, ‘flammulated’: 31, ‘grassy’: 32, ‘xanthic’: 33, ‘blove’: 34, ‘cerulean’: 34, ‘purple’: 35, ‘violescent’: 35, ‘violaceous’: 35, ‘albicans’: 37, ‘gray’: 90, ‘b_black’: ‘40’, ‘b_red’: ‘41’, ‘b_green’: ‘42’, ‘b_yellow’: ‘43’, ‘b_blue’: ‘44’, ‘b_magenta’: ‘45’, ‘b_cyan’: ‘46’, ‘b_white’: ‘47’, ‘lb_black’: ‘100’, ‘lb_red’: ‘101’, ‘lb_green’: ‘102’, ‘lb_yellow’: ‘103’, ‘lb_blue’: ‘104’, ‘lb_magenta’: ‘105’, ‘lb_cyan’: ‘106’, ‘lb_white’: ‘107’, ‘b_dark’: 40, ‘b_inky’: 40, ‘b_atramentous’: 40, ‘b_flammulated’: 41, ‘b_grassy’: 42, ‘b_xanthic’: 43, ‘b_blove’: 44, ‘b_cerulean’: 44, ‘b_purple’: 45, ‘b_violescent’: 45, ‘b_violaceous’: 45, ‘b_albicans’: 47, ‘b_gray’: 100, ‘s_off_all’: 0, ‘s_bright’: 1, ‘s_dim’: 2, ‘s_incline’: 3, ‘s_inclined’: 3, ‘s_underline’: 4, ‘s_emphasize’: 5, ‘s_overstriking’: 5, ‘s_inverse’: 7, ‘s_blanking’: 8, ‘s_strickout’: 9, ‘s_normal’: 22, ‘s_blank’: 22, ‘s_nothing’: 22}


    回页首

      教训:再次印证了“基础不牢,地动山摇”。学习,不可以放过细节。
      得到:bug不可怕,当bug消亡,就又一个知识点学到或者牢靠了。😊


    回页首

    __上一篇:__ 文本模式打印彩色直方统计图

    __下一篇:__ 

    我的HOT博:
    • 相关阅读:
      mindspore-RuntimeError: mindspore/ccsrc/backend/session/ascend_session.cc:
      3个线程打印ABC
      Leangoo敏捷工具管理轻量级项目群
      Anaconda虚拟环境下打开jupyter notebook
      汽车技术市场动态分析
      ELK日志收集系统
      ABAP 自定义屏幕上自定义字段 按空格没有记忆功能
      06 MyBatis缓存
      vue - Vue路由
      Multitor:一款带有负载均衡功能的多Tor实例创建工具
    • 原文地址:https://blog.csdn.net/m0_57158496/article/details/127137871