logo

з оператором на Python

У Python, із заявою використовується в обробці винятків, щоб зробити код чистішим і більш читабельним. Це спрощує керування загальними ресурсами, такими як файлові потоки. Зверніть увагу на наведений нижче приклад коду про те, як використання оператора with робить код чистішим.

Python3




рядковий масив Java





# file handling> # 1) without using with statement> file> => open>(>'file_path'>,>'w'>)> file>.write(>'hello world !'>)> file>.close()> # 2) without using with statement> file> => open>(>'file_path'>,>'w'>)> try>:> >file>.write(>'hello world'>)> finally>:> >file>.close()>



>

>

Python3




# using with statement> with>open>(>'file_path'>,>'w'>) as>file>:> >file>.write(>'hello world !'>)>

>

>

Зауважте, що на відміну від перших двох реалізацій, немає необхідності викликати file.close() під час використання оператора with. Сам оператор with забезпечує належне отримання та вивільнення ресурсів. Виняток під час виклику file.write() у першій реалізації може перешкодити належному закриттю файлу, що може спричинити кілька помилок у коді, тобто багато змін у файлах не набудуть чинності, доки файл не буде закрито належним чином. Другий підхід у наведеному вище прикладі подбає про всі винятки, але використання оператора with робить код компактнішим і більш читабельним. Таким чином, оператор with допомагає уникнути помилок і витоків, забезпечуючи належне звільнення ресурсу, коли код, який використовує ресурс, повністю виконано. Інструкція with широко використовується з файловими потоками, як показано вище, і з блокуваннями, сокетами, підпроцесами та telnet тощо.

шаблон проектування java

Підтримка оператора with у визначених користувачем об’єктах

У open() немає нічого особливого, що робить його придатним для використання з інструкцією with, і ту саму функціональність можна надати у визначених користувачем об’єктах. Підтримка оператора у ваших об’єктах гарантує, що ви ніколи не залишатимете жоден ресурс відкритим. Щоб використовувати оператор with у визначених користувачем об’єктах, вам потрібно лише додати методи __enter__() і __exit__() у методи об’єкта. Розглянемо наступний приклад для подальшого пояснення.

Python3




# a simple file writer object> class> MessageWriter(>object>):> >def> __init__(>self>, file_name):> >self>.file_name>=> file_name> > >def> __enter__(>self>):> >self>.>file> => open>(>self>.file_name,>'w'>)> >return> self>.>file> >def> __exit__(>self>,>*>args):> >self>.>file>.close()> # using with statement with MessageWriter> with MessageWriter(>'my_file.txt'>) as xfile:> >xfile.write(>'hello world'>)>

>

>

Давайте розглянемо наведений вище код. Якщо ви помітили, те, що слідує за ключовим словом with, є конструктором MessageWriter. Щойно виконання входить у контекст оператора with, створюється об’єкт MessageWriter, а потім python викликає метод __enter__(). У цьому методі __enter__() ініціалізуйте ресурс, який ви хочете використовувати в об’єкті. Цей метод __enter__() має завжди повертати дескриптор отриманого ресурсу. Що таке дескриптори ресурсів? Це дескриптори, надані операційною системою для доступу до запитуваних ресурсів. У наступному блоці коду file є дескриптором ресурсу файлового потоку.

вік Салман Кхан Кхан

Python




file> => open>(>'hello.txt'>)>

>

>

У наведеному вище прикладі MessageWriter метод __enter__() створює дескриптор файлу та повертає його. Ім'я xfile тут використовується для посилання на дескриптор файлу, який повертає метод __enter__(). Блок коду, який використовує отриманий ресурс, розміщується всередині блоку оператора with. Як тільки код всередині блоку with виконується, викликається метод __exit__(). Усі отримані ресурси звільняються в методі __exit__(). Ось як ми використовуємо оператор with із визначеними користувачем об’єктами. Цей інтерфейс методів __enter__() і __exit__(), який забезпечує підтримку оператора with у визначених користувачем об’єктах, називається Менеджер контексту .

Модуль contextlib

Контекстний менеджер на основі класу, як показано вище, не є єдиним способом підтримки оператора with у визначених користувачем об’єктах. The contextlib модуль надає ще кілька абстракцій, побудованих на базовому інтерфейсі менеджера контексту. Ось як ми можемо переписати менеджер контексту для об’єкта MessageWriter за допомогою модуля contextlib.

Python3

сортувати відро




from> contextlib>import> contextmanager> class> MessageWriter(>object>):> >def> __init__(>self>, filename):> >self>.file_name>=> filename> >@contextmanager> >def> open_file(>self>):> >try>:> >file> => open>(>self>.file_name,>'w'>)> >yield> file> >finally>:> >file>.close()> # usage> message_writer>=> MessageWriter(>'hello.txt'>)> with message_writer.open_file() as my_file:> >my_file.write(>'hello world'>)>

>

>

У цьому прикладі коду через врожайність у своєму визначенні функція open_file() є a функція генератора . Коли ця функція open_file() викликається, вона створює дескриптор ресурсу під назвою file. Потім цей дескриптор ресурсу передається викликаючому і представлений тут змінною my_file. Після виконання коду в блоці with програмне керування повертається до функції open_file(). Функція open_file() відновлює своє виконання та виконує код після оператора yield. Ця частина коду, яка з’являється після оператора yield, звільняє отримані ресурси. @contextmanager тут є a декоратор . Попередня реалізація на основі класів і ця реалізація контекстних менеджерів на основі генератора внутрішньо однакові. Хоча остання здається більш зрозумілою, вона потребує знань про генератори, декоратори та yield.