python - 如何正确关闭类打开的文件?
问题描述
我有一门课用来跟踪 ftp 下载的进度(使用ftplib
)。
我使用ftplib
withmultiprocessing
一次下载多个文件。
这是我第一次尝试在 Python 中使用类,我怀疑我是否正在关闭我在类中打开的文件。我认为相关的代码片段如下:
class track_transfer:
def __init__(self, size, fname):
self.file_name=fname
self.size_in_bytes=size
self.downloaded=0
self.file=open(fname, 'wb')
def __del__(self):
try:
self.file.close()
self.file=None
except:
pass
def update(self):
self.downloaded=self.file.tell()
if self.downloaded==self.size_in_bytes:
self.file.close()
如您所见,我尝试在两个地方关闭文件:一个在终结器中,另一个在类方法update()
中。
我想知道的是当我使用这个类时我的文件会正确关闭吗?
还是有更好的方法可以遵循?
更新
我想我可能需要在这里提供更多信息。
类track_transfer有另一个名为progress(self, data)的方法,定义如下:
def progress(self, data):
self.file.write(data)
self.update()
实例化类添加了更多信息,
tracker=track_transfer(size=fsize, fname=fname)
并下载文件,
ftp.retrbinary("RETR %s" %(fname),
callback=tracker.progress)
其中 ftp.retrbinary() 是ftplib库中定义的一种方法,用于从 ftp 服务器检索二进制文件。每当接收到数据块时,这将调用跟踪器objetc 的进度方法。这意味着在下载文件时会多次调用progress()方法。
解决方案
__del__
可能没有帮助:它只会在实例被垃圾收集时调用,track_transfer
并且它可能是唯一引用文件的东西 - 所以文件无论如何都会被垃圾收集,Python 将关闭当该对象被垃圾收集时文件。(__del__ 适用于您可能不会遇到的非常特殊用途的情况;Python 自然是一种垃圾收集语言,因此我们通常不会为“析构函数”之类的东西烦恼。)
管理文件对象生命周期的常规方法是使用with
块:
with open(path, mode) as f:
# do file operations
# file will be closed when the block is exited, even if by an exception etc.
这是有效的,因为文件是它自己的“上下文管理器”。将文件存储为类属性与这种方法不太吻合,因为您希望在一个类方法调用中打开文件并在稍后关闭它。但是我们可以通过使我们的类成为上下文管理器并使用它的上下文管理而不是文件来解决这个问题。
推荐阅读
- wordpress - AWS Wordpress HTTP 到 HTTPS 重定向不起作用
- python - 无法导入名称 _remove_dead_weakref
- pandas - 同时堆叠多组列
- amp-html - AMP:在 amp-list 中切换 CSS 类?
- google-bigquery - 用户在项目 gdelt-bq 中没有 bigquery.jobs.create 权限
- python - 发送参数时正则表达式不起作用
- alibaba-cloud - 如何在阿里云直邮中批量上传收件人列表?
- react-native - 图标不起作用
- javascript - .on('mouseover') 没有反馈信息
- javascript - 箭头函数可以作为repeat()的参数传递吗?