切记: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

  这段代码看不出啥毛病,但生成的字典,却少了高亮背景色(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. b_black, b_red, b_green, b_yellow, b_blue, b_magenta, b_cyan, b_white
2.

  第二次读取真的什么都没有!为啥会这样子?查看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)}")

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

输出

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

  在代码中把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)

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

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

得到想要的完整字典了😏

{‘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博:
    • 1
      点赞
    • 0
      收藏
      觉得还不错? 一键收藏
    • 打赏
      打赏
    • 0
      评论
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包

    打赏作者

    梦幻精灵_cq

    你的鼓励将是我创作的最大动力

    ¥1 ¥2 ¥4 ¥6 ¥10 ¥20
    扫码支付:¥1
    获取中
    扫码支付

    您的余额不足,请更换扫码支付或充值

    打赏作者

    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

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

    余额充值