2012-08-06 39 views
3

我正在使用Django来读取ajax上传的文件以将其存储在模型中。上传请求包含原始上传的图像数据。在Python中,在使用read()之后,我需要使用close()吗?

def my_view(request): 
    upload = request 
    model_instance.image_field.save(uniquename, ContentFile(upload.read())) 

如果有关系,我使用AmazonS3作为我上传文件的存储后端。

在包含此代码的函数中,有一处存在内存泄漏。

这样做后,我需要拨打upload.close()来释放资源/内存吗?
或者是我的内存问题来自其他问题,在这个函数的其他地方?

+0

我原以为AJAX会使用“POST”,或者Django会将它解释为多部分形式...... – 2012-08-06 18:36:26

+0

嗯,这是一个POST请求。如果我发布了整个视图,您会看到我已经检查了函数定义和相关代码之间的请求方法。但是因为我问的问题似乎并不重要,我没有包括它。 – 2012-08-06 18:45:20

回答

15

python垃圾收集器将在文件不再被引用时关闭文件。

如果您的upload变量是一个函数中的局部变量,它将在函数返回时被清除。因此,文件upload将在正常垃圾回收周期中自动关闭。

也就是说,关闭文件可能会更好。您可以使用该文件为context manager,它会自动关闭时的上下文中退出:

with open('yourfilepath.ext') as upload: 
    model_instance.image_field.save(uniquename, ContentFile(upload.read())) 

如果upload东西Django的产生对你来说,开放和准备好了,你仍然可以把它与自动关闭在contextlib.closing decorator

import contextlib 
with contextlib.closing(upload): 
    model_instance.image_field.save(uniquename, ContentFile(upload.read())) 

要回答你的问题的其余部分:你的泄漏是最有可能在其他地方。

+0

+1对于上下文管理器 - 值得注意的是,虽然CPython的GC将关闭超出范围和未引用的文件对象,但其他实现可能不会 - 也就是垃圾收集不可预测每个周期等... – 2012-08-06 18:30:32

+0

我意识到我的帖子被省略上传变量提及的关键细节以及它如何设置。我做了一些编辑以表明它实际上与代码描述的情况稍有不同。无论如何,我感谢您花时间来解决我的问题,并且很高兴知道我的泄漏很可能在其他地方。 – 2012-08-06 18:35:19

+0

@ClayWardell:和我的'contextlib.closing'示例不包含你的用例? – 2012-08-06 18:37:35

相关问题