前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于《生成器运行时机导致的难以察觉的 bug》勘误

关于《生成器运行时机导致的难以察觉的 bug》勘误

作者头像
青南
发布2020-06-01 15:05:35
3550
发布2020-06-01 15:05:35
举报
文章被收录于专栏:未闻Code

在文章《生成器运行时机导致的难以察觉的 bug》一文中,我最后解释为什么没有过滤掉无效数据的原因有问题。当时使用的是如下一段代码:

代码语言:javascript
复制
outer = 123

def i_am_generator():    
    print('生成器函数运行了。外部变量的值为:', outer)    
    yield

generator = i_am_generator()
print(f'现在返回的是一个生成器对象:{generator}')

outer = 456
for _ in generator:    
    ...

但这段代码中,生成器i_am_generator使用的始终是外部的变量。

但在实际举的例子中:

代码语言:javascript
复制
def do_filter(datas, to_filter):    
    for data in datas:        
        if to_filter in data:            
            continue        
    yield data

这个生成器是会接收传入参数的。它会使用参数传进来的值,而不是外部变量。在这种情况下,通过“值传递”进来的参数实际上是会有效的。我们修改一下原来的i_am_generator生成器:

代码语言:javascript
复制
outer = 123

def i_am_generator(data):    
    print('生成器函数运行了。外部变量的值为:', data)    
    yield

generator = i_am_generator(outer)
print(f'现在返回的是一个生成器对象:{generator}')

outer = 456
for _ in generator:    
    ...

运行效果如下图所示:

可以看到,在这种情况下,生成器里面打印出来的是outer变量修改之前的值,而不是修改后的值。outer变量一开始的值123通过值传递的方式传入生成器函数以后,就生效了。相当于复制了一份,所以原来的数据怎么修改都不会影响这个复制出来的数据。所以当我们后面修改outer的时候,并不会影响生成器中早已传入的值。

同理,对于我们举的过滤数据的例子,真正导致无法过滤无效数据的原因在这里:

代码语言:javascript
复制
def trash_filter():    
    datas = ['有效信息', '重要信息', '隐私信息', '脏数据', '保密信息', '无效数据', '大数据']    
    for word in ['无效', '脏']:        
        result = do_filter(datas, word)    
    return result

在这个循环里面,有两个生成器,但是他们都赋值到了result变量里面。所以第二个生成器就直接覆盖了第一个生成器。第一个生成器根本就没有执行。

所以最后执行的时候,实际上只有do_filter(datas, '脏')对应的生成器运行了。所以才会只过滤包含的内容。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 未闻Code 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档