代码之家  ›  专栏  ›  技术社区  ›  mikewaters

这是一个可以接受的蟒蛇习语吗?

  •  4
  • mikewaters  · 技术社区  · 15 年前

    我的问题是,我是否正确地使用了迭代器?这个成语可以接受吗?我刚开始使用Python。

    class FileParser:
      """ uses an open filehandle to do stuff """
    
    class BatchImporter:
      def __init__(self, files):
        self.files=files
    
      def parsers(self):
        for file in self.files:
          try:
            fh = open(file, "rb")
            parser = FileParser(fh)
            yield parser
          finally:
            fh.close()
    
      def verifyfiles(
      def cleanup(
    
    ---
    
    importer = BatchImporter(filelist)
    for p in BatchImporter.parsers():
      p.method1()
      ...
    
    4 回复  |  直到 15 年前
        1
  •  7
  •   Alex Martelli    15 年前

    像你一样,有一个生成器的方法是绝对好的。我建议您将所有类都设置为新样式(如果您使用的是python2,则任何一个都可以) __metaclass__ = type (object) 去你所有的基地 class

      def parsers(self):
        for afile in self.files:
            with open(afile, "rb") as fh:
                yield FileParser(fh)
    

    注意使用 afile file :后者是一个内置的标识符,一般来说,最好习惯

        2
  •  12
  •   Tim Pietzcker    15 年前

    你可以简化一件事:而不是 try ... finally with 块:

    with open(file, "rb") as fh:
        yield FileParser(fh)
    

    具有 方块在左边。

        3
  •  1
  •   user395760 user395760    15 年前

    如果你问我的话,这个设计很好,尽管你使用它的方式并不完全是惯用的。使用catch并可能重新引发异常(使用raise关键字 ,否则会弄乱stacktrace),对于奖励积分,不要catch:but catch Exception:(否则,会catch SystemExit和KeyboardInterrupt)。

    或者简单地使用timpietzcker所示的with语句。

        4
  •  0
  •   Marius Gedminas    15 年前

    一般来说,在生成一个解析器对象并试图读取它之后关闭文件是不安全的。考虑以下代码:

    parsers = list(BatchImporter.parsers())
    for p in parsers:
        # the file object that p holds will already be closed!
    

    如果您没有编写一个长时间运行的守护进程,那么大多数情况下您不会这样做 需要

    不过,注意释放资源是一个好习惯,因此我可能会这样编写FileParser类:

    class FileParser:
        def __init__(self, file_or_filename, closing=False):
            if hasattr(file_or_filename, 'read'):
                self.f = file_or_filename
                self._need_to_close = closing
            else:
                self.f = open(file_or_filename, 'rb')
                self._need_to_close = True
    
        def close(self):
            if self._need_to_close:
                self.f.close()
                self._need_to_close = False
    

    然后BatchImporter.parsers就会变成

        def parsers(self):
            for file in self.files:
                yield FileParser(file)
    

    或者,如果你喜欢函数式编程

        def parsers(self):
            return itertools.imap(FileParser, self.files)
    

    旁白:如果您是Python新手,我建议您看看 Python style guide