Автостопом по Python | страница 46



>>>> import threading

>>>> some_lock = threading.Lock()

>>>>

>>>> with some_lock:

>… ····# Создать Землю 1, запустить ее на десять миллионов лет…

>… ····print(

>… ········"Look at me: I design coastlines.\n"

>… ········"I got an award for Norway."

>… ····)

>…

Раньше это выглядело бы так:

>>>> import threading

>>>> some_lock = threading.Lock()

>>>>

>>>> some_lock.acquire()

>>>> try:

>… ····# Создать Землю 1, запустить ее на десять миллионов лет…

>… ····print(

>… ········"Look at me: I design coastlines.\n"

>… ········"I got an award for Norway."

>… ····)

>… finally:

>… ····some_lock.release()

Модуль стандартной библиотеки contextlib (https://docs.python.org/3/library/contextlib.html) предоставляет дополнительные инструменты, которые помогают преобразовать функции в менеджеры контекстов, навязать вызов метода close(), подавить исключения (в Python 3.4 и выше) и перенаправить стандартные потоки вывода и ошибок (в Python 3.4, 3.5 и выше). Рассмотрим пример использования функции contextlib.closing():

>>>> from contextlib import closing

>>>> with closing(open("outfile.txt", "w")) as output:

>… ····output.write("Well, he's…he's, ah…probably pining for the fjords.")

>…

>56

Но поскольку методы __enter__() и __exit__() определены для объекта, который отвечает за ввод/вывод для файла[41], мы можем использовать это выражение непосредственно, не закрывая файл самостоятельно:

>>>> with open("outfile.txt", "w") as output:

>····output.write(

>········"PININ' for the FJORDS?!?!?!? "

>········"What kind of talk is that? look, why did he fall "

>········"flat on his back the moment I got 'im home?\n"

>····)

>…

>123

Распространенные подводные камни

По большей части Python — чистый и надежный язык. Однако некоторые ситуации могут быть непонятны для новичков: какие-то из них созданы намеренно, но все равно могут удивить, другие можно считать особенностями языка. В целом все, что продемонстрировано в этом подразделе, относится к неоднозначному поведению, которое может показаться странным на первый взгляд, но впоследствии выглядит разумным (когда вы узнаете о причинах).

Изменяемые аргументы по умолчанию

Наиболее частый сюрприз, с которым сталкиваются новые программисты Python, — это отношение Python к изменяемым аргументам по умолчанию в определениях функции.

Что вы написали:

>def append_to(element, to=[]):

>····to.append(element)

>····return to

Чего вы ожидаете:

>my_list = append_to(12)

>print(my_list)

>my_other_list = append_to(42)

>print(my_other_list)

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