【发布时间】:2015-06-23 04:21:45
【问题描述】:
我需要完成的事情:
给定一个二进制文件,通过提供 TextIOBase API 的几种不同方式对其进行解码。理想情况下,这些后续文件可以传递,而无需明确跟踪它们的生命周期。
不幸的是,包装 BufferedReader 会
当TextIOWrapper 超出范围时,导致该阅读器被关闭。
这是一个简单的演示:
In [1]: import io
In [2]: def mangle(x):
...: io.TextIOWrapper(x) # Will get GCed causing __del__ to call close
...:
In [3]: f = io.open('example', mode='rb')
In [4]: f.closed
Out[4]: False
In [5]: mangle(f)
In [6]: f.closed
Out[6]: True
我可以在 Python 3 中通过覆盖 __del__ 来解决这个问题(这对于我的用例来说是一个合理的解决方案,因为我可以完全控制解码过程,我只需要在最后公开一个非常统一的 API):
In [1]: import io
In [2]: class MyTextIOWrapper(io.TextIOWrapper):
...: def __del__(self):
...: print("I've been GC'ed")
...:
In [3]: def mangle2(x):
...: MyTextIOWrapper(x)
...:
In [4]: f2 = io.open('example', mode='rb')
In [5]: f2.closed
Out[5]: False
In [6]: mangle2(f2)
I've been GC'ed
In [7]: f2.closed
Out[7]: False
但是这在 Python 2 中不起作用:
In [7]: class MyTextIOWrapper(io.TextIOWrapper):
...: def __del__(self):
...: print("I've been GC'ed")
...:
In [8]: def mangle2(x):
...: MyTextIOWrapper(x)
...:
In [9]: f2 = io.open('example', mode='rb')
In [10]: f2.closed
Out[10]: False
In [11]: mangle2(f2)
I've been GC'ed
In [12]: f2.closed
Out[12]: True
我花了一些时间盯着 Python 源代码,它在 2.7 和 3.4 之间看起来非常相似,所以我不明白为什么从 IOBase 继承的 __del__ 在 Python 2(或甚至在dir 中可见),但似乎仍然被执行。 Python 3 完全按预期工作。
有什么我可以做的吗?
【问题讨论】:
标签: python python-2.7 python-3.x garbage-collection