Python 如何仅提取.tar.gz成员的文件?

Python 如何仅提取.tar.gz成员的文件?,python,python-3.x,tar,Python,Python 3.x,Tar,我的目标是解压.tar.gz文件,而不是解压指向该文件的子目录 我的代码基于此,只是没有解包.zip,而是解包.tar.gz文件 我问这个问题是因为我得到的错误非常模糊,没有在我的代码中识别问题: import os import shutil import tarfile with tarfile.open('RTLog_20150425T152948.gz', 'r:gz') as tar: for member in tar.getmembers(): filen

我的目标是解压
.tar.gz
文件,而不是解压指向该文件的子目录

我的代码基于此,只是没有解包
.zip
,而是解包
.tar.gz
文件

我问这个问题是因为我得到的错误非常模糊,没有在我的代码中识别问题:

import os
import shutil
import tarfile

with tarfile.open('RTLog_20150425T152948.gz', 'r:gz') as tar:
    for member in tar.getmembers():
        filename = os.path.basename(member.name)
        if not filename:
            continue

        # copy file (taken from zipfile's extract)
        source = member
        target = open(os.path.join(os.getcwd(), filename), "wb")
        with source, target:
            shutil.copyfileobj(source, target)
如您所见,我从链接问题复制了代码,并尝试将其更改为处理.tar.gz成员而不是.zip成员。运行代码时,我得到以下错误:

Traceback (most recent call last):
  File "C:\Users\dzhao\Desktop\123456\444444\blah.py", line 27, in <module>
    with source, target:
AttributeError: __exit__
但这会在找不到文件时引发错误,这是可以理解的


我不明白什么?

这段代码对我有用:

import os
import shutil
import tarfile

with tarfile.open(fname, "r|*") as tar:
    counter = 0

    for member in tar:
        if member.isfile():
            filename = os.path.basename(member.name)
            if filename != "myfile": # do your check
                continue

            with open("output.file", "wb") as output: 
                shutil.copyfileobj(tar.fileobj, output, member.size)

            break # got our file

        counter += 1
        if counter % 1000 == 0:
            tar.members = [] # free ram... yes we have to do this manually
但是您的问题可能不是提取,而是您的文件确实不是.tar.gz,而只是一个.gz文件


编辑:也是因为python试图调用成员对象的函数(wich不存在),所以在with行中出现错误。

我知道我的文件肯定是a.tar.gz。当我删除带有源代码和目标代码的
行时,我最初的恐惧是正确的。似乎我的源不是一个类似文件的对象。阅读完
tar.fileobj
的功能后,我将尝试您的代码。修复方法是将源代码更改为
tar.fileobj
。有趣的是,当我在tar文档页面上使用ctrl+f时,它并不是一个函数。所以它一定是一个变量。但是重要的是,
tar.fileobj
是一个类似文件的对象,所以现在我的代码工作了=)谢谢!不客气。如果您处理的是大文件(100MB),我强烈建议包括免费的ram行。文档中没有提到这一点,但如果您的脚本突然失败,并且ram使用率非常高,这会让您大吃一惊。
import os
import shutil
import tarfile

with tarfile.open(fname, "r|*") as tar:
    counter = 0

    for member in tar:
        if member.isfile():
            filename = os.path.basename(member.name)
            if filename != "myfile": # do your check
                continue

            with open("output.file", "wb") as output: 
                shutil.copyfileobj(tar.fileobj, output, member.size)

            break # got our file

        counter += 1
        if counter % 1000 == 0:
            tar.members = [] # free ram... yes we have to do this manually