Những gì tôi cần phải thực hiện:Ngăn chặn TextIOWrapper từ đóng trên GC trong một/cách Py2 Py3 tương thích
Cho một tập tin nhị phân, giải mã nó trong một vài cách khác nhau cung cấp một API TextIOBase
. Lý tưởng nhất là các tệp tiếp theo này có thể được truyền mà không cần phải theo dõi tuổi thọ của chúng một cách rõ ràng.
Thật không may, việc gói BufferedReader
sẽ dẫn đến việc trình đọc đó bị đóng khi TextIOWrapper
nằm ngoài phạm vi.
Đây là một bản demo đơn giản này:
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
tôi có thể sửa lỗi này bằng Python 3 bằng cách ghi đè __del__
(đây là một giải pháp hợp lý đối với trường hợp sử dụng của tôi như tôi hoàn toàn kiểm soát quá trình giải mã, tôi chỉ cần để lộ một API rất đồng đều ở cuối):
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
Tuy nhiên điều này không làm việc trong 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
Tôi đã dành một chút thời gian nhìn chằm chằm vào mã nguồn Python và nó trông khá giống nhau giữa 2,7 và 3,4 vì vậy tôi không hiểu tại sao __del__
được thừa hưởng từ IOBase
không được ghi đè trong Python 2 (hoặc thậm chí có thể nhìn thấy trong dir
), nhưng dường như vẫn bị xử tử. Python 3 hoạt động chính xác như mong đợi.
Tôi có thể làm gì không?
Lý tưởng nhất là tôi muốn tránh vô hiệu hóa GC và bật lại sau đó, nhưng tôi chắc chắn đã nghĩ về điều đó ... – ebolyen