语句:with和tarfile
我尝试使用 with
语句和 tarfile 模块...
with tarfile.open('/dir/dir/dir.tar.gz', 'w:gz') as fl:
fl.add('/dir/dir/dir/', arcname = '/')
所以它显示了以下内容:
Traceback (most recent call last): File "", line 1, in AttributeError: 'TarFile' object has no attribute '__exit__'
我试着创建一个 tar.gz 文件,并使用这个语句来关闭它,但出现了错误。问题出在哪里呢?
谢谢!
3 个回答
你的错误信息复制得不太对。应该是 AttributeError: 'TarFile' object has no attribute '__exit__'
。
你显然在使用一个早于2.7的Python版本,而2.7版本增加了对“上下文管理器”协议的支持(这对于使用 with
语句是必要的),并且这个支持是针对 tarfile
模块的。
你有两个选择:
(1) 升级到2.7 但是 要注意,文档中说明这个支持并不完全:"""一个TarFile对象可以在 with
语句中作为上下文管理器使用。当代码块执行完毕后,它会自动关闭。不过请注意,如果发生异常,打开的写入归档不会被最终化;只有内部使用的文件对象会被关闭。
(2) 继续使用2.6或者其他版本,手动用try/except/finally来处理。
也许你使用的Python标准库版本不够新。查看一下这份文档,里面提到:
- 在2.7版本中新增:支持上下文管理器协议。
顺便说一下,当你在使用Python标准库时遇到不明白的行为,查阅文档应该是你首先要做的事情。特别是阅读那一页,如果你明白整个“上下文管理”系统(对象协议)是相对较新的,并且是通过Python中那个比较难找的with
关键字来访问的,那么就能解答你的疑问。
这个对象协议实现了一些有用的隐式语义,比如关闭文件、释放锁以及其他清理和资源管理的事情……即使在出现异常的情况下也是如此。其实这就是在try:
...finally:
...的基础上加了一些语法糖,并且你可以为自己的类添加一些特性来利用这些支持。
要进一步理解这些内容,最好去阅读一下:with语句上下文管理器。
你可以使用 contextlib.closing,比如:
from contextlib import closing
with closing(tarfile.open('/dir/dir/dir.tar.gz', 'w:gz')) as fl:
fl.add('/dir/dir/dir/', arcname = '/')
来自文档的说明:
即使发生错误,当退出 with 块时,
page.close()
也会被调用。
contextlib.closing
从 Python 2.5 开始就可以用了(可能甚至更早就有了...)。