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

Python循环传入tar文件列表时tarfile解压报AttributeError

问题根本原因

核心错误是变量命名冲突导致导入的标准库模块被覆盖:

  • 顶部通过import tarfile导入压缩处理模块后,全局命名空间中tarfile本应指向该模块对象
  • 后续遍历文件列表的for循环使用了tarfile作为迭代变量名:for tarfile in tar_list:,循环启动后会将全局作用域的tarfile重新赋值为遍历得到的字符串类型文件路径,原本的模块引用被彻底覆盖
  • 封装的extract_fn函数内部调用tarfile.open()时,会从全局作用域查找tarfile变量,此时拿到的是字符串路径,字符串对象不存在open方法,因此抛出AttributeError: 'str' object has no attribute 'open'

这个逻辑完全匹配你观察到的现象:

  • 单独调用extract_fn时还未执行for循环,全局tarfile仍为模块对象,因此解压正常
  • 函数内仅打印参数时不会调用tarfile模块的方法,自然不会触发报错
  • 给传入参数转字符串的操作没有解决全局模块被覆盖的问题,因此报错完全不变
修复方案

从根源规避命名冲突即可,推荐修改迭代变量名,不要和导入的模块、函数重名,同时可以优化资源释放逻辑避免句柄泄漏,修正后可运行的完整代码如下:

#!/usr/bin/python3
import tarfile
import glob
import os

name = "myself"
backup_path = "/tmp/test"
# 原代码中db变量未定义,需提前赋值
db = "your_custom_db_name"
# 推荐用os.path.join处理路径拼接,避免斜杠写错
tar_location = os.path.join(backup_path, db)
tar_list = glob.glob(os.path.join(tar_location, "walfiles-*.tar.gz"))

tar_destination = os.path.join(backup_path, "extracted")
# 提前创建目标目录避免解压报错
os.makedirs(tar_destination, exist_ok=True)

def extract_fn(tar_path, extract_dest):
    # 用with上下文管理器自动关闭文件,避免异常时资源泄漏
    # 明确指定gz格式读取,避免自动检测格式的兼容问题
    with tarfile.open(tar_path, "r:gz") as tar_obj:
        tar_obj.extractall(extract_dest)

# 迭代变量改名为tar_path,不再和tarfile模块重名
for tar_path in tar_list:
    extract_fn(tar_path, tar_destination)

其他可选修复方式

如果不想修改迭代变量名,也可以在导入模块时给tarfile起别名,比如导入时写import tarfile as tar_lib,后续函数内统一用tar_lib.open()调用即可,但这种方式可读性不如直接修改冲突变量名,不推荐使用。

额外注意点

你之前测试时写的遍历代码中,将目标路径变量误写为wal_destination,和实际定义的tar_destination不一致,运行时会触发NameError,需要注意变量名拼写一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 09:54:30