Computer >> Máy Tính >  >> Lập trình >> Python

Tiện ích Python cho ngữ cảnh với câu lệnh (contextlib)

mô-đun contextlib của thư viện chuẩn của Python xác định lớp ContextManager mà đối tượng của nó quản lý đúng cách các tài nguyên trong một chương trình. Python có với từ khóa hoạt động với trình quản lý ngữ cảnh. Đối tượng tệp (được trả về bởi hàm open () tích hợp sẵn) hỗ trợ API ContextManager. Do đó, chúng tôi thường tìm thấy từ khóa được sử dụng khi làm việc với tệp.

Khối mã sau sẽ mở một tệp và ghi một số dữ liệu vào đó. Sau khi thao tác kết thúc, tệp sẽ bị đóng, do lỗi bộ mô tả tệp nào có khả năng bị rò rỉ dẫn đến tệp bị hỏng.

f = open("file.txt","w")
f.write("hello world")
f.close()

Tuy nhiên, hoạt động tương tự với tệp được thực hiện bằng khả năng quản lý ngữ cảnh của tệp bằng cú pháp sau.

with open("file.txt","w") as f:
f.write("hello world")
print ("file is closed")

Như đã đề cập ở trên, đối tượng tệp thực thi ContextManager. Nó được kích hoạt bởi với từ khóa. Khối with chứa các câu lệnh được xử lý cho đối tượng tệp. Ngay sau khi khối kết thúc, đối tượng tệp sẽ tự động bị đóng (Phương thức close () không cần được gọi một cách rõ ràng). Bất kỳ đối tượng nào được đặt trong khối sẽ chỉ hoạt động bên trong khối và sẽ được xử lý ngay lập tức ở phần cuối của nó.

Lớp ContextManager có hai phương thức thiết yếu __enter __ () và __exit __ ()

__enter __ () - sẽ được gọi khi với khối bắt đầu. Nó chỉ ra rằng chương trình đã nhập ngữ cảnh thời gian chạy liên quan đến đối tượng này.

__exit __ () - được gọi khi với khối kết thúc. Nó chỉ ra rằng chương trình thoát khỏi ngữ cảnh thời gian chạy liên quan đến đối tượng này.

Đối tượng tệp cũng sở hữu hai phương thức này và có thể được xác nhận bằng phiên thông dịch sau.

>>> f = open("file.txt","w")
>>> f.__enter__()
<_io.TextIOWrapper name = 'file.txt' mode = 'w' encoding = 'cp1252'>
>>> f.write("hello world")
11
>>> f.__exit__()
>>> f.write("hello world")
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
f.write("hello world")
ValueError: I/O operation on closed file.

Khi phương thức __exit __ () được gọi, tệp sẽ bị đóng. Đó là lý do tại sao ValueError xuất hiện khi chúng tôi cố gắng ghi một số dữ liệu vào tệp sau khi nó bị đóng.

Dưới đây là một cách sử dụng tổng quát hơn của contextManager. Đầu tiên, chúng ta xác định một lớp với các phương thức __enter __ () và __exit __ () và bật contextManager cho đối tượng của nó bằng câu lệnh.

import contextlib
class WithExample:
   def __init__(self):
      print ("object initialized")
   def __enter__(self):
      print ("entered context")
   def __exit__(self, *args):
      print ("exited context")
with WithExample() as w:
print ('this is a contextlib example')
print ('used by with statement')
print ('end of with block')

Kết quả cho thấy rằng ngay sau khi khối with bắt đầu, phương thức __enter __ () được thực thi. Các câu lệnh trong khối được xử lý. Khi hết khối, phương thức __exit __ () tới sẽ tự động được gọi.

object initialized
entered context
this is a contextlib example
used by with statement
exited context
end of with block

Mô-đun contextlib có @contextmanager decorator với sự trợ giúp của chúng tôi có thể viết một hàm nhà máy dựa trên trình tạo để tự động hỗ trợ bằng câu lệnh. Việc quản lý ngữ cảnh của đối tượng tệp với decorator như sau -

from contextlib import contextmanager
@contextmanager
def openfile(name):
   try:
      f = open(name, 'w')
      yield f
   finally:
      f.close()
with openfile(file.txt') as f:
f.write('hello world')
print ('file is closed')

Do đó, ContextManager là một tính năng rất hữu ích của Python để quản lý hiệu quả các tài nguyên trong một chương trình.