美文网首页
Python yield

Python yield

作者: 天空蓝雨 | 来源:发表于2019-12-06 19:51 被阅读0次

    如果嵌套递归 的迭代器,例如下面错误的代码

        def iter_tar_file(self,file):
                if not tarfile.is_tarfile(file):
                    raise ValueError("请传入有效的tar文件")
                tar = tarfile.TarFile.open(file)  
                names = tar.getnames()  
    
                for filename in names:
                    if filename.endswith("tar") or filename.endswith("tar.gz"):
                        self.iter_tar_file(filename)  # 递归返回
                        continue
                    bytes_count = tar.gettarinfo(filename).size
                    yield bytes_count
    

    外面调用

    for i in iter_tar_file:
        print(i)
    

    self.iter_tar_file(filename) # 递归返回
    上面一行的数据是不会反回的。只会返回最外层的,因为哪一个递归函数,相当于没有接收对象,虽然有返回值,但是并没有传到外面。
    错误的改进方法

    yield self.iter_tar_file(filename)  # 递归返回 
    
    

    这样做只是yield 一个迭代器对象,并没有把里面的值返回
    迭代器吗,只能返回到调用他的那一层,并不会越级返回,
    <generator object get_tar_size at 0x0000000004D5EB88>


    image.png

    对此有两个解决办法:

    第一种就是用 for 把递归返回到外面

    for i  in self.iter_tar_file(filename)  # 递归返回
        yield  i    # 这样 内层的  yield 就可以逐级返回到最外层了
                        continue
    
    image.png
    第二种方法:yield from
    https://www.python.org/dev/peps/pep-0380/
    yield from   self.iter_tar_file(filename)
    
    
    image.png

    yield from 用于把子级迭代器 返回到外面 效果是等同于 for 循环的
    可以这样想

    def  a():
        if xxx:
              for i  in  iter :
                      yield  i 
    yield  xx
    

    这样所有的yield 值都可以返回给最外面的函数了,yield 也起到了for 循环的效果,但是更简洁,是 pep 8 规范呢

    递归的如果需要 yield 返回数据,需要 用 for 循环嵌套,或者跟简单就是 用 yield form iterobj 返回 不yield 后者直接yield 都拿不到数据

    相关文章

      网友评论

          本文标题:Python yield

          本文链接:https://www.haomeiwen.com/subject/taidvctx.html