python-254Đọc toàn bộ đề miễn phí

Bộ ghi dấu khối lệnh với `__enter__` và `__exit__`

Câu lệnh with chỉ dựa vào hai phương thức: enter chạy khi mở khối và exit

PythonCơ bản14 phút

Tiến độ của tôi ở bài này

Điểm và code bạn nộp được lưu vào tài khoản sau khi chấm bài.

Đang tải điểm của bạn…

Kiến thức và chủ đề

protocolscontext-managerdunder-methodsentry-ramp

Kiến thức tiên quyết: python-basics, python-classes-intro, python-with-statement.

Nội dung đề bài

Mô tả bài toán

Câu lệnh with chỉ dựa vào hai phương thức: enter chạy khi mở khối và exit chạy khi rời khối, kể cả khi khối đó ném lỗi. Giá trị exit trả về quyết định có nuốt lỗi hay không. Tự viết một bộ ghi dấu khối lệnh là cách gọn nhất để thấy rõ cả hai lời gọi và thứ tự của chúng.

Yêu cầu

Cài đặt lớp Tracer:

  • init(self, name="main"): nhận tên khối; ném ValueError nếu name không phải

chuỗi hoặc là chuỗi rỗng. Lưu tên trong self._name, danh sách sự kiện trong self._events, số khối đã mở self._opened và số khối đã đóng self._closed.

  • enter(self): ghi thêm sự kiện chuỗi "enter:<tên>:<độ sâu>" với độ sâu là số

khối đang mở TRƯỚC khi mở khối này, rồi tăng self._opened; trả về self._name.

  • exit(self, exc_type=None, exc=None, tb=None): tăng self._closed, ghi thêm sự

kiện "exit:<tên>:<độ sâu>" với độ sâu là số khối đang mở SAU khi đóng khối này, và trả về False để không bao giờ nuốt ngoại lệ.

  • events(self): trả về bản sao danh sách sự kiện.
  • depth(self): trả về số khối đang mở, tức self._opened - self._closed.
  • measure(self): dùng chính cú pháp with self as name: rồi trả về name, để chứng

minh đối tượng dùng được như một trình quản lý ngữ cảnh.

Quy ước nộp bài

Nộp lớp Tracer trong solution.py. Hệ thống tự khởi tạo lớp bằng Tracer(name=...), gọi trực tiếp cả enter, exit lẫn các phương thức thường và bắt ngoại lệ ValueError; không dùng stdin/stdout.

Input

Hệ thống khởi tạo lớp bằng tham số từ khoá name, rồi gọi lần lượt các phương thức theo kịch bản của từng bộ test, kể cả gọi thẳng enter và exit.

Output

Danh sách giá trị trả về theo đúng thứ tự gọi. enter trả về tên khối, exit trả về False, events trả về danh sách chuỗi.

Ràng buộc

  • Sự kiện có đúng dạng "enter:<tên>:<độ sâu>" hoặc "exit:<tên>:<độ sâu>".
  • Độ sâu khi vào là số khối đang mở trước khi vào; khi ra là số khối đang mở sau khi ra.
  • exit luôn trả False; việc mở và đóng khối không được nuốt ngoại lệ.

Ví dụ 1

Input

Tracer(init={"name": "main"}, methods=[{"method": "__enter__"}, {"method": "events"}, {"method": "__exit__"}, {"method": "events"}])

Output

["main", ["enter:main:0"], false, ["enter:main:0", "exit:main:0"]]

Ví dụ 2

Input

Tracer(init={"name": "load"}, methods=[{"method": "measure"}, {"method": "events"}])

Output

["load", ["enter:load:0", "exit:load:0"]]

Giải thích

Với name="main" rồi gọi enter(), events(), exit(), events() ta được "main", ["enter:main:0"], False, ["enter:main:0", "exit:main:0"].

3 cấp độ gợi ýMở dần khi bạn thật sự cần hỗ trợ.
Phân tích lời giảiGiải thích hướng tư duy và thuật toán.
Code tham khảoDùng để đối chiếu sau khi tự làm.

Gợi ý và lời giải chỉ mở sau khi bạn bấm Nộp bài. Giáo viên và quản trị viên mở được ngay.

Nhóm Zalo