如何嵌套任意数量的Python文件上下文管理器?

前端之家收集整理的这篇文章主要介绍了如何嵌套任意数量的Python文件上下文管理器?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我想采用任意数量的路径来表示嵌套的tar档案,并对最里面的档案执行操作.问题是,嵌套可以是任意的,因此我需要的上下文管理器的数量也是任意的.

举个例子:

  1. ARCHIVE_PATH = "path/to/archive.tar"
  2. INNER_PATHS = (
  3. "nested/within/archive/one.tar","nested/within/archive/two.tar",# Arbitary number of these
  4. )
  5. def list_inner_contents(archive_path,inner_paths):
  6. with TarFile(archive_path) as tf1:
  7. with TarFile(fileobj=tf1.extractfile(inner_paths[0])) as tf2:
  8. with TarFile(fileobj=tf2.extractfile(inner_paths[1])) as tf3:
  9. # ...arbitary level of these!
  10. return tfX.getnames()
  11. contents = list_inner_contents(ARCHIVE_PATH,INNER_PATHS))

我不能使用with语句的nesting syntax,因为可以有任意数量的级别来嵌套.我不能使用contextlib.nested因为文档在那里说:

…using nested() to open two files is a programming error as the first file will not be closed promptly if an exception is thrown when opening the second file.

有没有办法使用语言结构来执行此操作,还是需要手动管理我自己的打开文件对象堆栈?

最佳答案
对于这种情况,您可以使用递归.对于这种情况来说感觉最自然(当然如果在Python中没有特殊处理):

  1. ARCHIVE_PATH = "path/to/archive.tar"
  2. INNER_PATHS = [
  3. "nested/within/archive/one.tar",# Arbitary number of these
  4. ]
  5. def list_inner_contents(archive_path,inner_paths):
  6. def rec(tf,rest_paths):
  7. if not rest_paths:
  8. return tf.getnames()
  9. with TarFile(fileobj=tf.extractfile(rest_paths[0])) as tf2:
  10. return rec(tf2,rest_paths[1:])
  11. with TarFile(archive_path) as tf:
  12. try:
  13. return rec(tf,inner_paths)
  14. except RuntimeError:
  15. # We come here in case the inner_paths list is too long
  16. # and we go too deeply in the recursion
  17. return None

猜你在找的Python相关文章