You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用TarFile.extractfile()作为上下文管理器触发AttributeError: __enter__

问题分析

AttributeError: __enter__ 错误的核心原因是:tarfile.extractfile() 返回的 ExtractFile 对象未实现上下文管理器所需的 __enter__ 和 __exit__ 方法,导致无法直接用 with 语句进行资源管理。这种情况常见于 Python 3.2 之前的版本,或是部分特殊场景下的 tar 文件对象。

解决方法

方法1:用contextlib.closing包装返回对象

contextlib.closing 可以为任何带有 close() 方法的对象补全上下文管理器接口,完美适配 ExtractFile:

from contextlib import closing

# 修改readfile函数
if tarfile.is_tarfile(data):
    tardata = tarfile.open(data, "r")
    files = tardata.getmembers()
    
    def readfile(data_pt):
        # 先过滤目录,避免extractfile返回None
        if not data_pt.isfile():
            return None
        return closing(tardata.extractfile(data_pt))

修改后你的原循环代码可正常运行,closing 会在 with 块结束时自动调用文件的 close() 方法。

方法2:手动管理文件的打开与关闭

如果不想引入额外模块,直接用 try/finally 手动管控资源:

for file in files:
    # 跳过目录,避免处理空对象
    if not file.isfile():
        continue
    openfile = readfile(file)
    try:
        molecules.append(process_file_fn(openfile))
    finally:
        openfile.close()

方法3:升级Python版本

从 Python 3.2 开始,tarfile.ExtractFile 已原生支持上下文管理器接口。若你使用的是较老版本,升级到 3.2+ 后无需修改代码即可直接使用原逻辑。

额外注意点

  • tardata.getmembers() 会返回 tar 包中的目录对象,调用 extractfile() 处理目录会返回 None,同样会触发 with 语句报错,必须用 data_pt.isfile() 做判断过滤。
  • 你的 .tar.bz2 格式文件无需额外指定压缩模式,tarfile.open(data, "r") 会自动识别压缩格式,当前参数是正确的。

内容的提问来源于stack exchange,提问作者Rose Vanilla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 10:12:44