Trong this question, tôi đã xác định trình quản lý ngữ cảnh chứa trình quản lý ngữ cảnh. Cách chính xác nhất để thực hiện việc lồng ghép này là gì? Tôi đã gọi số self.temporary_file.__enter__()
trong số self.__enter__()
. Tuy nhiên, trong self.__exit__
, tôi khá chắc chắn tôi phải gọi self.temporary_file.__exit__(type_, value, traceback)
trong một khối cuối cùng trong trường hợp ngoại lệ được nêu ra. Tôi có nên đặt thông số type_, value và traceback nếu có sự cố trong số self.__exit__
không? Tôi đã kiểm tra contextlib
nhưng không thể tìm thấy bất kỳ tiện ích nào để trợ giúp việc này.Quản lý ngữ cảnh lồng nhau của Python
đang gốc từ câu hỏi:
import itertools as it
import tempfile
class WriteOnChangeFile:
def __init__(self, filename):
self.filename = filename
def __enter__(self):
self.temporary_file = tempfile.TemporaryFile('r+')
self.f = self.temporary_file.__enter__()
return self.f
def __exit__(self, type_, value, traceback):
try:
try:
with open(self.filename, 'r') as real_f:
self.f.seek(0)
overwrite = any(
l != real_l
for l, real_l in it.zip_longest(self.f, real_f))
except IOError:
overwrite = True
if overwrite:
with open(self.filename, 'w') as real_f:
self.f.seek(0)
for l in self.f:
real_f.write(l)
finally:
self.temporary_file.__exit__(type_, value, traceback)
Điều này thật sự rất hay. Tôi sẽ để câu hỏi mở một chút trong trường hợp câu hỏi này tạo ra bất kỳ câu trả lời hay nào khác. –
Sử dụng '@ contextlib.contextmanager' rất thuận tiện, nhưng vẫn có những trường hợp thích hợp để sử dụng một lớp với các phương thức' __enter__' và '__exit__' được định nghĩa theo cách thủ công. Bạn có lời khuyên nào về việc đó không? – Zearin
Vâng, hãy làm điều đó khi nó thuận tiện hơn - ví dụ khi đối tượng cần làm nhiều hơn chỉ là một trình quản lý ngữ cảnh (mặc dù trong trường hợp đó bạn cũng nên xem xét thêm một phương thức @ contextlib.contextmanager). –