Библиотека Python разработчика | Книги по питону
19.5K subscribers
1.05K photos
391 videos
82 files
989 links
Полезные материалы для питониста по Фреймворкам Django, Flask, FastAPI, Pyramid, Tornado и др.

По всем вопросам @evgenycarter

РКН clck.ru/3Ko7Hq
Download Telegram
Иногда нужно выполнить блок кода с несколькими менеджерами контекста:


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
Все объекты, которые в настоящий момент существуют в памяти интерпретатора, можно получить с помощью 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, при возникновении нового исключения внутри блока 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:


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 нет поддержки асинхронных операций с файлами. Чтобы сделать их неблокирующими, нужно использовать отдельные потоки.

Для асинхронного выполнения кода в потоке следует использовать метод loop.run_in_executor.

Сторонний модуль aiofiles делает всё это за тебя, предоставляя простой и удобный интерфейс:


async with aiofiles.open('filename', mode='r') as f:
contents = await f.read()


👉@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
Существует две встроенные функции, которые позволяют анализировать итерируемые объекты без необходимости писать тривиальные и избыточные циклы for. Это all и any.

any возвращает True, если хотя бы одно значение истинно; all возвращает True, только если все значения истинны. Для пустого итерируемого объекта all возвращает True, а anyFalse.

Обе функции особенно полезны в сочетании со списковыми включениями (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 в атрибуте класса:


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
🔍Тестовое собеседование на Python-бекендера с разработчиком из Avito во вторник

17 июня(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Python-разработчика.

Как это будет:
📂 Даня, разработчик из Авито, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Даня будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Дане

Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.

Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_py_bot

Реклама. ООО "ШОРТКАТ", ИНН: 9731139396, erid: 2VtzqubLfbk
Please open Telegram to view this post
VIEW IN TELEGRAM
Если ты хочешь запустить код с изменённой глобальной переменной, лучше использовать контекстный менеджер, а не менять её напрямую:


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
Ты можешь создавать словари двумя способами: с помощью литералов или функции 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
Начиная с Python 3.5, стало возможно использовать распаковку в литералах словарей и списков.

Пример со словарём:


{**{'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