Sử dụng with
mà không cần as
vẫn mang đến cho bạn chính xác teardown; nó không giúp bạn có được một đối tượng địa phương mới đại diện cho bối cảnh.
Lý do bạn muốn điều này là đôi khi chính bối cảnh không trực tiếp hữu ích - nói cách khác, bạn chỉ sử dụng nó cho các hiệu ứng phụ của bối cảnh của nó nhập và thoát. Ví dụ, với một đối tượng Lock
, bạn phải có đối tượng cho khối with
là hữu ích - vì vậy, ngay cả khi bạn cần nó trong khối, không có lý do gì để rebind nó vào một tên khác. Quay trở lại đầu trang Điều này cũng đúng khi bạn sử dụng contextlib.closing
trên một đối tượng không phải là người quản lý ngữ cảnh — bạn đã có chính đối tượng, vì vậy ai quan tâm đến sản lượng closing
?
Với thứ gì đó như sh.sudo
, thậm chí không có đối tượng mà bạn muốn sử dụng trong bất kỳ khoảng thời gian nào.
Ngoài ra còn có các trường hợp mà điểm của người quản lý ngữ cảnh ở đó để lưu trữ và tự động khôi phục một số trạng thái. Ví dụ: bạn có thể muốn viết một termios.tcsetattr
-stasher, vì vậy bạn có thể gọi tty.setraw()
bên trong khối. Bạn không quan tâm đối tượng stash trông như thế nào, tất cả những gì bạn quan tâm là nó được khôi phục tự động.
decimal.localcontext
có thể hoạt động theo bất kỳ cách nào - bạn có thể truyền cho đối tượng bạn đã có (và do đó không cần tên mới) hoặc chuyển cho đối tượng tạm thời chưa được đặt tên hoặc chỉ lưu trữ bối cảnh được khôi phục tự động. Nhưng trong bất kỳ trường hợp nào.
Có một số trường hợp lai đôi khi bạn muốn ngữ cảnh, đôi khi bạn không muốn. Ví dụ, nếu bạn chỉ muốn một giao dịch cơ sở dữ liệu để tự động cam kết, bạn có thể viết with autocommit(db.begin()):
, bởi vì bạn sẽ không truy cập nó bên trong khối. Nhưng nếu bạn muốn tự động khôi phục trừ khi bạn cam kết rõ ràng, bạn có thể viết with autorollback(db.begin()) as trans:
, vì vậy bạn có thể bên trong khối. (Tất nhiên thường xuyên, bạn sẽ thực sự muốn có một giao dịch mà cam kết về xuất cảnh bình thường và cuộn lại ngoại lệ, như trong ví dụ transaction
PEP 343 's. Nhưng tôi không thể nghĩ ra một ví dụ lai tốt hơn ở đây ...)
PEP 343 và những người tiền nhiệm của nó (PEP 310, PEP 340, và những thứ khác được liên kết từ 343) giải thích tất cả điều này ở một mức độ nào đó, nhưng có thể hiểu được rằng bạn sẽ không đọc nó một cách bình thường - có rất nhiều thông tin không liên quan và chủ yếu chỉ giải thích tổng quan về dặm cao và sau đó là chi tiết cấp độ triển khai, bỏ qua mọi thứ ở giữa.
Có thể bạn không muốn thực hiện 'với foo:' trong trường hợp _this_. 'foo' là một cuộc gọi và kết quả của cuộc gọi đó gần như chắc chắn sẽ là trình quản lý ngữ cảnh mà bạn muốn thoát, chứ không phải là chính nó. Nhưng 'với bar:' hoàn toàn hợp lý ở đây, như trong câu trả lời của @ freakish. – abarnert
Bạn đúng; Tôi đã thay đổi nó. – fvrghl