Иногда нужно выполнить блок кода с несколькими менеджерами контекста:
Начиная с Python 2.7 и 3.1, это можно записать в одной конструкции
Раньше для этого использовали функцию
Если же число менеджеров контекста заранее неизвестно, лучше подойдёт более продвинутый инструмент.
👉@BookPython
with open('f') as f:
with open('g') as g:
with open('h') as h:
pass
Начиная с Python 2.7 и 3.1, это можно записать в одной конструкции
with
:
o = open
with o('f') as f, o('g') as g, o('h') as h:
pass
Раньше для этого использовали функцию
contextlib.nested
:
with nested(o('f'), o('g'), o('h')) as (f, g, h):
pass
Если же число менеджеров контекста заранее неизвестно, лучше подойдёт более продвинутый инструмент.
contextlib.ExitStack
позволяет открывать любое число контекстов в произвольный момент, но гарантирует корректный выход из них в конце:
with ExitStack() as stack:
f = stack.enter_context(o('f'))
g = stack.enter_context(o('g'))
other = [
stack.enter_context(o(filename))
for filename in filenames
]
👉@BookPython
Все объекты, которые в настоящий момент существуют в памяти интерпретатора, можно получить с помощью
👉@BookPython
gc.get_objects()
:
In [1]: class A:
...: def __init__(self, x):
...: self._x = x
...:
...: def __repr__(self):
...: class_name = type(self).__name__
...: x = self._x
...: return f'{class_name}({x!r})'
...:
In [2]: A(1)
Out[2]: A(1)
In [3]: A(2)
Out[3]: A(2)
In [4]: A(3)
Out[4]: A(3)
In [5]: [x for x in gc.get_objects() if isinstance(x, A)]
Out[5]: [A(1), A(2), A(3)]
👉@BookPython
Начиная с Python 3.0, при возникновении нового исключения внутри блока
Кроме того, вы можете явно указать причинное исключение, использовав конструкцию
👉@BookPython
except
перехваченное исключение автоматически сохраняется в атрибуте __context__
создаваемого исключения. В результате при выводе будут показаны оба исключения:
try:
1 / 0
except ZeroDivisionError:
raise ValueError('Zero!')
(most recent call last):
File "test.py", line 2, in <module>
1 / 0
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "test.py", line 4, in <module>
raise ValueError('Zero!')
ValueError: Zero!
Кроме того, вы можете явно указать причинное исключение, использовав конструкцию
raise … from
. Тогда в атрибут __cause__
нового исключения будет помещено исходное:
division_error = None
try:
1 / 0
except ZeroDivisionError as e:
division_error = e
raise ValueError('Zero!') from division_error
(most recent call last):
File "test.py", line 4, in <module>
1 / 0
ZeroDivisionError: division by zero
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "test.py", line 8, in <module>
raise ValueError('Zero!') from division_error
ValueError: Zero!
👉@BookPython
In:
Out:
Цифры 0 1 2 3 4 5 6 7 8 9 — это не единственные символы, которые считаются цифрами. Python следует правилам Unicode и считает «цифрами» сотни различных символов. Вот полный список таких символов.
Это влияет на такие функции, как
👉@BookPython
int('୧৬𝟙༣')
Out:
1613
Цифры 0 1 2 3 4 5 6 7 8 9 — это не единственные символы, которые считаются цифрами. Python следует правилам Unicode и считает «цифрами» сотни различных символов. Вот полный список таких символов.
Это влияет на такие функции, как
int
, unicode.isdecimal
и даже re.match
:
# Пример 1
int('෯')
# Вывод:
9
# Пример 2
'٢'.isdecimal()
# Вывод:
True
# Пример 3
import re
bool(re.match(r'\d', '౫'))
# Вывод:
True
👉@BookPython
>>> bool(datetime(2018, 1, 1).time())
False
>>> bool(datetime(2018, 1, 1, 13, 12, 11).time())
True
До Python 3.5 объекты
datetime.time()
считались ложными, если они представляли полночь по UTC. Это могло приводить к трудноуловимым ошибкам. В следующих примерах if not
может выполниться не потому, что created_time
равен None
, а потому, что время — полночь.
def create(created_time=None) -> None:
if not created_time:
created_time = datetime.now().time()
Можно исправить это, явно проверяя на
None
:
def create(created_time=None) -> None:
if created_time is None:
created_time = datetime.now().time()
👉@BookPython
В Python нет поддержки асинхронных операций с файлами. Чтобы сделать их неблокирующими, нужно использовать отдельные потоки.
Для асинхронного выполнения кода в потоке следует использовать метод
Сторонний модуль aiofiles делает всё это за тебя, предоставляя простой и удобный интерфейс:
👉@BookPython
Для асинхронного выполнения кода в потоке следует использовать метод
loop.run_in_executor
.Сторонний модуль aiofiles делает всё это за тебя, предоставляя простой и удобный интерфейс:
async with aiofiles.open('filename', mode='r') as f:
contents = await f.read()
👉@BookPython
Иногда нужно создать функцию на основе более универсальной.
Например, у функции
Это полезно, когда нужно передать функцию как аргумент другой, более общей функции, но при этом некоторые аргументы должны быть зафиксированы:
Без
👉@BookPython
Например, у функции
int()
есть параметр base
, который мы хотим зафиксировать, чтобы получить новую функцию base2
:
>>> int("10")
10
>>> int("10", 2)
2
>>> def base2(x):
... return int(x, 2)
...
>>> base2("10")
2
functools.partial
позволяет сделать то же самое, но точнее и семантически понятнее:
base2 = partial(int, base=2)
Это полезно, когда нужно передать функцию как аргумент другой, более общей функции, но при этом некоторые аргументы должны быть зафиксированы:
>>> map(partial(int, base=2), ["1", "10", "100"])
[1, 2, 4]
Без
partial
пришлось бы делать так:
>>> map(lambda x: int(x, base=2), ["1", "10", "100"])
[1, 2, 4]
👉@BookPython
Существует две встроенные функции, которые позволяют анализировать итерируемые объекты без необходимости писать тривиальные и избыточные циклы
Обе функции особенно полезны в сочетании со списковыми включениями (list comprehensions):
Функции
👉@BookPython
for
. Это all
и any
.any
возвращает True
, если хотя бы одно значение истинно; all
возвращает True
, только если все значения истинны. Для пустого итерируемого объекта all
возвращает True
, а any
— False
.Обе функции особенно полезны в сочетании со списковыми включениями (list comprehensions):
package_broken = any(
part.is_broken() for part in package.get_parts()
)
package_ok = all(
part.ok() for part in package.get_parts()
)
Функции
any
и all
зачастую взаимозаменяемы благодаря законам де Моргана. Используй ту, с которой код будет понятнее.👉@BookPython
Если ты хочешь, чтобы у объектов класса автоматически увеличивался ID, это можно реализовать, отслеживая текущий ID в атрибуте класса:
Обрати внимание, что нельзя использовать
Лучше использовать фабричный метод вместо
Эта версия также проще для тестирования, так как можно легко задать любой ID вручную.
👉@BookPython
class Task:
_task_id = 0
def __init__(self):
self._id = self._task_id
type(self)._task_id += 1
Обрати внимание, что нельзя использовать
self._task_id += 1
— это создаст атрибут _task_id
внутри экземпляра, а не изменит значение на уровне класса.Лучше использовать фабричный метод вместо
__init__
, чтобы код выглядел аккуратнее:
class Task:
_task_id = 0
def __init__(self, task_id):
self._id = task_id
@classmethod
def create(cls):
obj = cls(cls._task_id)
cls._task_id += 1
return obj
Эта версия также проще для тестирования, так как можно легко задать любой ID вручную.
👉@BookPython
17 июня(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Python-разработчика.
Как это будет:
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_py_bot
Реклама. ООО "ШОРТКАТ", ИНН: 9731139396, erid: 2VtzqubLfbk
Please open Telegram to view this post
VIEW IN TELEGRAM
Если ты хочешь запустить код с изменённой глобальной переменной, лучше использовать контекстный менеджер, а не менять её напрямую:
👉@BookPython
from contextlib import contextmanager
QUIT_MESSAGE = 'Bye'
def print_quit_mesage():
global QUIT_MESSAGE
print(QUIT_MESSAGE)
@contextmanager
def global_variable_changed(name, value):
orig_value = globals()[name]
globals()[name] = value
yield
globals()[name] = orig_value
with global_variable_changed(
'QUIT_MESSAGE',
'Tschüss'
):
print_quit_mesage()
👉@BookPython
Ты можешь создавать словари двумя способами: с помощью литералов или функции
Литералы работают быстрее, чем
Во-первых, не нужно ставить дополнительные кавычки. Однако это работает только в том случае, если все ключи — допустимые идентификаторы Python:
Во-вторых, ты не сможешь случайно указать один и тот же ключ дважды:
В-третьих, легко создать новый словарь на основе уже существующего:
Но учти, что ключи нельзя переопределять при таком способе:
👉@BookPython
dict
:
>>> dict(a=1, b=2)
{'a': 1, 'b': 2}
>>> {'a': 1, 'b': 2}
{'a': 1, 'b': 2}
Литералы работают быстрее, чем
dict
, но у функции есть свои преимущества.Во-первых, не нужно ставить дополнительные кавычки. Однако это работает только в том случае, если все ключи — допустимые идентификаторы Python:
>>> dict(a=1)
{'a': 1}
>>> dict(1='a')
File "<stdin>", line 1
SyntaxError: keyword can't be an expression
Во-вторых, ты не сможешь случайно указать один и тот же ключ дважды:
>>> {'a': 1, 'a': 1}
{'a': 1}
>>> dict(a=1, a=1)
File "<stdin>", line 1
SyntaxError: keyword argument repeated
В-третьих, легко создать новый словарь на основе уже существующего:
>>> d = dict(b=2)
>>> dict(a=1, **d)
{'a': 1, 'b': 2}
Но учти, что ключи нельзя переопределять при таком способе:
>>> dict(b=3, **d)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: type object got multiple values for keyword argument
👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
Начиная с Python 3.5, стало возможно использовать распаковку в литералах словарей и списков.
Пример со словарём:
Пример со списком:
Для словарей такая форма даже мощнее, чем функция
👉@BookPython
Пример со словарём:
{**{'a': 1}, 'b': 2, **{'c': 3}}
# Результат: {'a': 1, 'b': 2, 'c': 3}
Пример со списком:
[1, 2, *[3, 4]]
# Результат: [1, 2, 3, 4]
Для словарей такая форма даже мощнее, чем функция
dict
, потому что позволяет переопределять значения:
{**{'a': 1, 'b': 1}, 'a': 2, **{'b': 3}}
# Результат: {'a': 2, 'b': 3}
👉@BookPython
🚀 Подборка Telegram каналов для программистов
Системное администрирование, DevOps 📌
https://t.me/bash_srv Bash Советы
https://t.me/win_sysadmin Системный Администратор Windows
https://t.me/sysadmin_girl Девочка Сисадмин
https://t.me/srv_admin_linux Админские угодья
https://t.me/linux_srv Типичный Сисадмин
https://t.me/devopslib Библиотека девопса | DevOps, SRE, Sysadmin
https://t.me/linux_odmin Linux: Системный администратор
https://t.me/devops_star DevOps Star (Звезда Девопса)
https://t.me/i_linux Системный администратор
https://t.me/linuxchmod Linux
https://t.me/sys_adminos Системный Администратор
https://t.me/tipsysdmin Типичный Сисадмин (фото железа, было/стало)
https://t.me/sysadminof Книги для админов, полезные материалы
https://t.me/i_odmin Все для системного администратора
https://t.me/i_odmin_book Библиотека Системного Администратора
https://t.me/i_odmin_chat Чат системных администраторов
https://t.me/i_DevOps DevOps: Пишем о Docker, Kubernetes и др.
https://t.me/sysadminoff Новости Линукс Linux
1C разработка 📌
https://t.me/odin1C_rus Cтатьи, курсы, советы, шаблоны кода 1С
https://t.me/DevLab1C 1С:Предприятие 8
https://t.me/razrab_1C 1C Разработчик
https://t.me/buh1C_prog 1C Программист | Бухгалтерия и Учёт
https://t.me/rabota1C_rus Вакансии для программистов 1С
Программирование C++📌
https://t.me/cpp_lib Библиотека C/C++ разработчика
https://t.me/cpp_knigi Книги для программистов C/C++
https://t.me/cpp_geek Учим C/C++ на примерах
Программирование Python 📌
https://t.me/pythonofff Python академия.
https://t.me/BookPython Библиотека Python разработчика
https://t.me/python_real Python подборки на русском и английском
https://t.me/python_360 Книги по Python
Java разработка 📌
https://t.me/BookJava Библиотека Java разработчика
https://t.me/java_360 Книги по Java Rus
https://t.me/java_geek Учим Java на примерах
GitHub Сообщество 📌
https://t.me/Githublib Интересное из GitHub
Базы данных (Data Base) 📌
https://t.me/database_info Все про базы данных
Мобильная разработка: iOS, Android 📌
https://t.me/developer_mobila Мобильная разработка
https://t.me/kotlin_lib Подборки полезного материала по Kotlin
Фронтенд разработка 📌
https://t.me/frontend_1 Подборки для frontend разработчиков
https://t.me/frontend_sovet Frontend советы, примеры и практика!
https://t.me/React_lib Подборки по React js и все что с ним связано
Разработка игр 📌
https://t.me/game_devv Все о разработке игр
Библиотеки 📌
https://t.me/book_for_dev Книги для программистов Rus
https://t.me/programmist_of Книги по программированию
https://t.me/proglb Библиотека программиста
https://t.me/bfbook Книги для программистов
БигДата, машинное обучение 📌
https://t.me/bigdata_1 Big Data, Machine Learning
Программирование 📌
https://t.me/bookflow Лекции, видеоуроки, доклады с IT конференций
https://t.me/rust_lib Полезный контент по программированию на Rust
https://t.me/golang_lib Библиотека Go (Golang) разработчика
https://t.me/itmozg Программисты, дизайнеры, новости из мира IT
https://t.me/php_lib Библиотека PHP программиста 👨🏼💻👩💻
https://t.me/nodejs_lib Подборки по Node js и все что с ним связано
https://t.me/ruby_lib Библиотека Ruby программиста
https://t.me/lifeproger Жизнь программиста. Авторский канал.
QA, тестирование 📌
https://t.me/testlab_qa Библиотека тестировщика
Шутки программистов 📌
https://t.me/itumor Шутки программистов
Защита, взлом, безопасность 📌
https://t.me/thehaking Канал о кибербезопасности
https://t.me/xakep_2 Хакер Free
Книги, статьи для дизайнеров 📌
https://t.me/ux_web Статьи, книги для дизайнеров
Математика 📌
https://t.me/Pomatematike Канал по математике
https://t.me/phis_mat Обучающие видео, книги по Физике и Математике
https://t.me/matgeoru Математика | Геометрия | Логика
Excel лайфхак📌
https://t.me/Excel_lifehack
https://t.me/mir_teh Мир технологий (Technology World)
Вакансии 📌
https://t.me/sysadmin_rabota Системный Администратор
https://t.me/progjob Вакансии в IT
Системное администрирование, DevOps 📌
https://t.me/bash_srv Bash Советы
https://t.me/win_sysadmin Системный Администратор Windows
https://t.me/sysadmin_girl Девочка Сисадмин
https://t.me/srv_admin_linux Админские угодья
https://t.me/linux_srv Типичный Сисадмин
https://t.me/devopslib Библиотека девопса | DevOps, SRE, Sysadmin
https://t.me/linux_odmin Linux: Системный администратор
https://t.me/devops_star DevOps Star (Звезда Девопса)
https://t.me/i_linux Системный администратор
https://t.me/linuxchmod Linux
https://t.me/sys_adminos Системный Администратор
https://t.me/tipsysdmin Типичный Сисадмин (фото железа, было/стало)
https://t.me/sysadminof Книги для админов, полезные материалы
https://t.me/i_odmin Все для системного администратора
https://t.me/i_odmin_book Библиотека Системного Администратора
https://t.me/i_odmin_chat Чат системных администраторов
https://t.me/i_DevOps DevOps: Пишем о Docker, Kubernetes и др.
https://t.me/sysadminoff Новости Линукс Linux
1C разработка 📌
https://t.me/odin1C_rus Cтатьи, курсы, советы, шаблоны кода 1С
https://t.me/DevLab1C 1С:Предприятие 8
https://t.me/razrab_1C 1C Разработчик
https://t.me/buh1C_prog 1C Программист | Бухгалтерия и Учёт
https://t.me/rabota1C_rus Вакансии для программистов 1С
Программирование C++📌
https://t.me/cpp_lib Библиотека C/C++ разработчика
https://t.me/cpp_knigi Книги для программистов C/C++
https://t.me/cpp_geek Учим C/C++ на примерах
Программирование Python 📌
https://t.me/pythonofff Python академия.
https://t.me/BookPython Библиотека Python разработчика
https://t.me/python_real Python подборки на русском и английском
https://t.me/python_360 Книги по Python
Java разработка 📌
https://t.me/BookJava Библиотека Java разработчика
https://t.me/java_360 Книги по Java Rus
https://t.me/java_geek Учим Java на примерах
GitHub Сообщество 📌
https://t.me/Githublib Интересное из GitHub
Базы данных (Data Base) 📌
https://t.me/database_info Все про базы данных
Мобильная разработка: iOS, Android 📌
https://t.me/developer_mobila Мобильная разработка
https://t.me/kotlin_lib Подборки полезного материала по Kotlin
Фронтенд разработка 📌
https://t.me/frontend_1 Подборки для frontend разработчиков
https://t.me/frontend_sovet Frontend советы, примеры и практика!
https://t.me/React_lib Подборки по React js и все что с ним связано
Разработка игр 📌
https://t.me/game_devv Все о разработке игр
Библиотеки 📌
https://t.me/book_for_dev Книги для программистов Rus
https://t.me/programmist_of Книги по программированию
https://t.me/proglb Библиотека программиста
https://t.me/bfbook Книги для программистов
БигДата, машинное обучение 📌
https://t.me/bigdata_1 Big Data, Machine Learning
Программирование 📌
https://t.me/bookflow Лекции, видеоуроки, доклады с IT конференций
https://t.me/rust_lib Полезный контент по программированию на Rust
https://t.me/golang_lib Библиотека Go (Golang) разработчика
https://t.me/itmozg Программисты, дизайнеры, новости из мира IT
https://t.me/php_lib Библиотека PHP программиста 👨🏼💻👩💻
https://t.me/nodejs_lib Подборки по Node js и все что с ним связано
https://t.me/ruby_lib Библиотека Ruby программиста
https://t.me/lifeproger Жизнь программиста. Авторский канал.
QA, тестирование 📌
https://t.me/testlab_qa Библиотека тестировщика
Шутки программистов 📌
https://t.me/itumor Шутки программистов
Защита, взлом, безопасность 📌
https://t.me/thehaking Канал о кибербезопасности
https://t.me/xakep_2 Хакер Free
Книги, статьи для дизайнеров 📌
https://t.me/ux_web Статьи, книги для дизайнеров
Математика 📌
https://t.me/Pomatematike Канал по математике
https://t.me/phis_mat Обучающие видео, книги по Физике и Математике
https://t.me/matgeoru Математика | Геометрия | Логика
Excel лайфхак📌
https://t.me/Excel_lifehack
https://t.me/mir_teh Мир технологий (Technology World)
Вакансии 📌
https://t.me/sysadmin_rabota Системный Администратор
https://t.me/progjob Вакансии в IT
Telegram
Bash Советы
🚀 Секреты и советы по Bash
🔹 Полезные трюки, хитрые однострочники и лайфхаки для работы в терминале.
🔹 Автоматизация, скрипты и оптимизация работы в Linux.
🔹 Стать мастером Bash легко – просто подпишись!
💻 Прокачивай терминал вместе с нами! 👇
🔹 Полезные трюки, хитрые однострочники и лайфхаки для работы в терминале.
🔹 Автоматизация, скрипты и оптимизация работы в Linux.
🔹 Стать мастером Bash легко – просто подпишись!
💻 Прокачивай терминал вместе с нами! 👇