With python что это
Перейти к содержимому

With python что это

  • автор:

Конструкция with#

В Python существует более удобный способ работы с файлами, чем те, которые использовались до сих пор — конструкция with :

In [1]: with open('r1.txt', 'r') as f: . for line in f: . print(line) . ! service timestamps debug datetime msec localtime show-timezone year service timestamps log datetime msec localtime show-timezone year service password-encryption service sequence-numbers ! no ip domain lookup ! ip ssh version 2 !

Кроме того, конструкция with гарантирует закрытие файла автоматически.

Обратите внимание на то, как считываются строки файла:

for line in f: print(line) 

Когда с файлом нужно работать построчно, лучше использовать такой вариант.

В предыдущем выводе, между строками файла были лишние пустые строки, так как print добавляет ещё один перевод строки.

Чтобы избавиться от этого, можно использовать метод rstrip :

In [2]: with open('r1.txt', 'r') as f: . for line in f: . print(line.rstrip()) . ! service timestamps debug datetime msec localtime show-timezone year service timestamps log datetime msec localtime show-timezone year service password-encryption service sequence-numbers ! no ip domain lookup ! ip ssh version 2 ! In [3]: f.closed Out[3]: True

И конечно же, с конструкцией with можно использовать не только такой построчный вариант считывания, все методы, которые рассматривались до этого, также работают:

In [4]: with open('r1.txt', 'r') as f: . print(f.read()) . ! service timestamps debug datetime msec localtime show-timezone year service timestamps log datetime msec localtime show-timezone year service password-encryption service sequence-numbers ! no ip domain lookup ! ip ssh version 2 !

Открытие двух файлов#

Иногда нужно работать одновременно с двумя файлами. Например, надо записать некоторые строки из одного файла, в другой.

В таком случае, в блоке with можно открывать два файла таким образом:

In [5]: with open('r1.txt') as src, open('result.txt', 'w') as dest: . : for line in src: . : if line.startswith('service'): . : dest.write(line) . : In [6]: cat result.txt service timestamps debug datetime msec localtime show-timezone year service timestamps log datetime msec localtime show-timezone year service password-encryption service sequence-numbers 

Это равнозначно таким двум блокам with:

In [7]: with open('r1.txt') as src: . : with open('result.txt', 'w') as dest: . : for line in src: . : if line.startswith('service'): . : dest.write(line) . : 

Оператор With в Python

Python – язык программирования, наделенный достаточно большим количеством инструментов, функций и встроенных стандартных команд. С их помощью удается создавать совершенно разное программное обеспечение. Огромную роль в таких приложениях может сыграть менеджер контекста.

Базовые определения

Перед тем как начинать изучение любого инструмента языка программирования, нужно запомнить несколько базовых определений:

  1. Переменная – единица хранения информации. Является именованной областью памяти.
  2. Функция – блок кода, который выполняет определенные операции для получения задуманного результата.
  3. Оператор – объект, который умеет при помощи специальных команд манипулировать операндами.
  4. Операнд – объекты кода, которыми умеет управлять оператор.
  5. Алгоритм – набор инструкций и указаний, необходимых для решения поставленной изначально задачи.

В Питоне присутствует множество операторов. Один из них используется для формирования менеджера контекста. Далее речь зайдет о With в Python.

Предназначение With и менеджера

With появился в Питоне с версии 2.5. Данный оператор является достаточно полезным. Данная функция используется почти каждым написанным на языке приложением.

With выполняет различные действия при активации:

  • обрабатывает открытие/закрытие ресурсов;
  • закрывает автоматически часть приложения, с которой больше не нужно работать.

Все это необходимо для того, чтобы грамотно распределять ресурсы устройства, а также оптимизировать функционирование имеющейся памяти.

Менеджер в Питоне

The Python – простой и функциональный язык разработки приложений. В нем можно обрабатывать файлы. В C и некоторых других ЯП для этого требуется вручную открывать и закрывать документ. Ниже – фрагмент кода, который помогает это сделать:

With делает это автоматически. Каждый раз открывать и закрывать файлы самостоятельно при формировании приложения на The Python не придется. У оператора with имеется контекст (блок), в котором он будет действовать.

Когда приложение выходит из соответствующего контекста, with будет автоматически закрывать ранее используемый файл. Все это приводит к тому, что рассматриваемый элемент в the Python носит название «диспетчер контекста».

with open(‘input.txt’, ‘r’) as file_obj:
Выше – пример того, как данная «опция» используется при обработке файлов. The operator будет всегда в конце закрывать документ. Это относится даже к ситуациям, когда само приложение работает/завершается некорректно.

Применение

Возможность использования with in the statement реализована в большом количестве классов Питона. Данный элемент the code:

  1. Сохраняет ссылку на объект в объекте контекста. Так называют объект, содержащий дополнительную информацию о своем состоянии (область видимости, модуль и так далее).
  2. После создания объекта the operator вызывает метод под названием __enter__ dunder для соответствующего компонента. С его помощью происходит открытие ресурсов для объекта. Может использоваться при реализации сохранения состояния элемента.

При работе с with необходимо обратить внимание на ключевое слово as in the statement. Оно фактически возвращает объект контекста. As a используется для того, чтобы получить элемент, возвращаемый при помощи функции open().

As in statements можно не использовать, если у разработчика имеется ссылка на исходный объект контекста в другом месте.

Далее предстоит перейти во вложенный блок операторов. Когда он закончится или встретится исключение, приложение выполнит для объекта the context __exit__. Она выступает в качестве первой функции безопасности. Используется всегда для того, чтобы высвободить ресурсы устройства и выйти из заданного контекста.

Собственные менеджеры – как создать

Для более удобного и быстрого изучения in The Python оператора with as необходимо научиться создавать собственные context managers для заданного класса.

Выше – пример того, как происходит формирование упомянутого элемента в The Python. Здесь есть метод __init__. Он написан для обработчика, устанавливает начальное состояние объектов и соответствующих переменных.

Также есть метод __enter__, сохраняющий состояние объекта и открывающий его. Это позволяет попасть внутрь заданного блока. После выполнения соответствующего фрагмента кода диспетчер выполнит __exit__, чтобы восстановить прежнее состояние the object. Файл будет закрыт.

На экране появится такая надпись вследствие выполнения приложения.

Методы

При работе с Python with a statement, необходимо помнить о методах для менеджеров контекста. Их всего два:

  1. __enter__. Используется для того, чтобы войти в context времени выполнения. Либо возвращает текущий объект, либо другой связанный элемент. Возвращаемое значение будет привязано к идентификатору в виде предположения with.
  2. Метод __exit__. Применяется для возврата результата логического характера. Указывает на любое произошедшее исключение. Если есть одно исключение для with, оно будет переведено в конец блока.

Выше – наглядный пример того, как реализованы эти методы in The Python with statement. А вот результат, который будет выведен на экран.

Здесь можно увидеть наглядный пример использования with…as, but лучше всего закончить дистанционные компьютерные курсы по The Python, чтобы быстро освоить язык и всего его возможности.

with

Инструкция позволяет задействовать менеджер контекста для исполнения кода, находящего в её теле. Это, в частности, позволяет обособить блоки, использующие try except finally и повысить шансы их повторного использования.

 class MyContextManager(object):

def __enter__(self):
print('enter')

def __exit__(self, exc_type, exc_value, traceback):
print('exit')



with MyContextManager(): # enter
print('do') # do
# exit

Последовательность действий инструкции

1. Выражение после with вычисляется для получения менеджера контекста;
2. Для последующего использования запоминается метод менеджера __exit__();
3. Вызывается метод менеджера __enter__();
4. Если после as указана цель, то в неё помещается результат __enter__() ;

На заметку

Инструкция гарантирует вызов __exit__() , в случаях, когда __enter__() отработал без ошибок. Если исключение происходит во время назначения цели as , то оно равноценно исключению, произошедшему в теле.

5. Выполняется тело инструкции;
6. Вызывается метод __exit__() . Если выход обусловлен исключением, то данные о нём передаются в метод. Если __exit__() вернул ложь , то по выходу из контекстного менеджера исключение продолжит своё восхождение по стеку. В случае истины , исключение будет подавлено.

+py3.1 Несколько менеджеров можно указать через запятую:

 with manager1() as one, manager2() as two: 
do()

# То же самое, вложенно:
with manager1() as one:
with manager2() as two:
do()

Блог питониста

Изображение гика

Данная статья — перевод c моим небольшим дополнением, оригинал.

Часто ключевое слово with не до конца понятно даже опытным разработчикам.

Как и многие другие вещи в Python, ключевое слово with на самом деле очень просто устроено, это станет очевидно, как только вы поймете какую проблему оно решает. Посмотрите на данный код:

1 set things up 2 try: 3 do something 4 finally: 5 tear things down 

Здесь под «set things up» подразумевается открытие файла, подключение какого-то внешнего ресурса, а под «tear things down» — закрытие файла, отключение от внешнего ресурса. Конструкция try-finally гарантирует, что «tear things down» часть будет всегда исполнена, даже если код, делающий что-либо вызовет ошибку или не завершится.

Если это часто ипользуется, то было бы удобно вынести код “set things up” и “tear things down” в библиотечную функцию, чтобы легко ее использовать. Конечно, вы можете сделать что-то вроде:

 1 def controlled_execution(callback): 2 set things up 3 try: 4 callback(thing) 5 finally: 6 tear things down 7 8 def my_function(thing): 9 do something 10 11 controlled_execution(my_function) 

Но это немного многословно, особенно если вам нужно изменять локальные переменные. Другой подход заключается в использовании генератора, а затем нужно использовать for-in:

1 def controlled_execution(): 2 set things up 3 try: 4 yield thing 5 finally: 6 tear things down 7 8 for thing in controlled_execution(): 9 do something with thing 

Но yield нельзя было использовать внутри try-finally в 2.4 и раньше. И немного странно использовать loop для чего-то, что вы хотите выполнить один раз.

Поэтому, после рассмотрения нескольких вариантов, Гвидо Ван Россум и python-dev команда наконец решили использовать объект вместо генератора, чтобы контролировать поведение данного кода:

1 class controlled_execution: 2 def __enter__(self): 3 set things up 4 return thing 5 def __exit__(self, type, value, traceback): 6 tear things down 7 8 with controlled_execution() as thing: 9 some code 

Теперь, когда «with» выражение исполняется, Python исполняет выражение, вызывает метод __enter__ с полученным значением (которое называется «context guard»), затем присваивает переменной переданной словом as (в данном случае thing) то, что возвращает метод __enter__. Далее, Python исполняет тело (в данное случае some code), и в любом случае вызывает метод __exit__.

В добавок, __exit__ может подавить исключение, вернуть вместо него True. Например, этот __exit__ заменяет TypeError, но разрешает все другие исключения:

1 def __exit__(self, type, value, traceback): 2 return isinstance(value, TypeError) 
 1 class controlled_execution: 2 def __enter__(self): 3 print('in enter') 4 print(self) 5 return ('test') 6 7 def __exit__(self, type, value, traceback): 8 print('in exit') 9 10 11 with controlled_execution() as thing: 12 print('in here') 13 print(thing) 14 raise TypeError 
alex@vostro:~/projects/blog_materials$ python test.py in enter in here test in exit Traceback (most recent call last): File "test.py", line 14, in raise TypeError TypeError
 1 class controlled_execution: 2 def __enter__(self): 3 print('in enter') 4 print(self) 5 return ('test') 6 7 def __exit__(self, type, value, traceback): 8 print('in exit') 9 return isinstance(value, TypeError) 10 11 12 with controlled_execution() as thing: 13 print('in here') 14 print(thing) 15 raise TypeError 
alex@vostro:~/projects/blog_materials$ python test.py in enter in here test in exit

В Python 2.5 у объекта типа file появились методы __enter__ и __exit__, первый просто возвращает сам объект, а второй закрывает файл:

>>> f = open("x.txt") >>> f >>> f.__enter__() >>> f.read(1) 'X' >>> f.__exit__(None, None, None) >>> f.read(1) Traceback (most recent call last): File "", line 1, in ValueError: I/O operation on closed file

Поэтому, чтобы открыть файл, сделать что-то с содержимым и точно закрыть его, вы просто делаете так:

1 with open("x.txt") as f: 2 data = f.read() 3 do something with data 

Это не было очень сложно, правда?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *