27 ноября собираемся на Pytup: митап Яндекса для Python-разработчиков и ML-инженеров 🚀
Присоединяйтесь в Екатеринбурге или онлайн, чтобы в неформальной обстановке поговорить о Python, машинном обучении и технологиях, которые двигают индустрию вперед.
В программе выступлений:
> Арсений Саблин, разработчик системы контроля качества умных устройств на производстве (Яндекс Алиса), поделится, как используется Python при тестировании станции с Алисой;
> Никита Улько, техлид VK Tech, разберет чистую архитектуру с практической точки зрения: за что ее ценят и как гибко применять ее принципы, фокусируясь на решении конкретных проблем;
> Егор Гордовский, технический менеджер проектов Yandex Cloud, расскажет о сложном техническом организме, помогающем превратить код в работающий сервис — дата-центре.
Помимо докладов участников в Екатеринбурге ждет дискуссия Snake Pit, а также соревнования по классической «Змейке» и гонки на игрушечных роботах-доставщиках.
📅 27 ноября в 17.00 (по Екб)
📍 Екатеринбург (креативный кластер «Домна») + онлайн
Регистрация на митап
Присоединяйтесь в Екатеринбурге или онлайн, чтобы в неформальной обстановке поговорить о Python, машинном обучении и технологиях, которые двигают индустрию вперед.
В программе выступлений:
> Арсений Саблин, разработчик системы контроля качества умных устройств на производстве (Яндекс Алиса), поделится, как используется Python при тестировании станции с Алисой;
> Никита Улько, техлид VK Tech, разберет чистую архитектуру с практической точки зрения: за что ее ценят и как гибко применять ее принципы, фокусируясь на решении конкретных проблем;
> Егор Гордовский, технический менеджер проектов Yandex Cloud, расскажет о сложном техническом организме, помогающем превратить код в работающий сервис — дата-центре.
Помимо докладов участников в Екатеринбурге ждет дискуссия Snake Pit, а также соревнования по классической «Змейке» и гонки на игрушечных роботах-доставщиках.
📅 27 ноября в 17.00 (по Екб)
📍 Екатеринбург (креативный кластер «Домна») + онлайн
Регистрация на митап
❤1👍1🔥1
Когда вы создаете кастомный метод
Пример простого кода:
Проблема возникает, если вы вызываете
Для решения этой проблемы можно использовать декоратор
Теперь код работает корректно:
📲 Мы в MAX
👉@BookPython
__repr__ для объекта, обычно нужно включить представление его атрибутов. Однако важно помнить, что нужно явно вызывать repr(), так как форматирование вызывает str() вместо repr().Пример простого кода:
class Pair:
def __init__(self, left, right):
self.left = left
self.right = right
def __repr__(self):
class_name = type(self).__name__
repr_left = repr(self.left)
repr_right = repr(self.right)
return f'{class_name}({repr_left}, {repr_right})'
Проблема возникает, если вы вызываете
repr для объекта, который содержит ссылку на самого себя. Это может привести к рекурсии:
In : p = Pair(1, 2)
In : p
Out: Pair(1, 2)
In : p.right = p
In : p
Out: [...]
RecursionError: maximum recursion depth exceeded while calling a Python object
Для решения этой проблемы можно использовать декоратор
reprlib.recursive_repr, который обрабатывает рекурсивные вызовы:
@reprlib.recursive_repr()
def __repr__(self):
class_name = type(self).__name__
repr_left = repr(self.left)
repr_right = repr(self.right)
return f'{class_name}({repr_left}, {repr_right})'
Теперь код работает корректно:
In : p = Pair(1, 2)
In : p.right = p
In : p
Out: Pair(1, ...)
👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍1
Тесты могут требовать временные файлы или директории. Для этого отлично подойдет модуль
Так как временные файлы обычно нужно удалять после использования,
📲 Мы в MAX
👉@BookPython
tempfile.Так как временные файлы обычно нужно удалять после использования,
tempfile предоставляет как контекстный менеджер, так и простые функции:
import os
import tempfile
with tempfile.TemporaryDirectory() as dir_path:
open(os.path.join(dir_path, 'a'), 'w').close()
open(os.path.join(dir_path, 'b'), 'w').close()
open(os.path.join(dir_path, 'c'), 'w').close()
assert files_of(dir_path) == ['a', 'b', 'c']
👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Нативные значения
Это означает, что в большинстве случаев вы работаете с приближениями, а не с точными значениями:
Модуль
Однако и этого может быть недостаточно:
Для точных вычислений можно использовать
Очевидным ограничением остается то, что иррациональные числа (например, π) все равно будут представлены только в приближенной форме.
📲 Мы в MAX
👉@BookPython
float в Python используют аппаратные возможности вашего компьютера, поэтому любое значение внутренне представлено в виде двоичной дроби.Это означает, что в большинстве случаев вы работаете с приближениями, а не с точными значениями:
In : format(0.1, '.17f')
Out: '0.10000000000000001'
Модуль
decimal позволяет использовать десятичную арифметику с произвольной точностью:
In : Decimal(1) / Decimal(3)
Out: Decimal('0.3333333333333333333333333333')
Однако и этого может быть недостаточно:
In [61]: Decimal(1) / Decimal(3) * Decimal(3) == Decimal(1)
Out[61]: False
Для точных вычислений можно использовать
fractions, где любое число хранится в виде рационального:
In : Fraction(1) / Fraction(3) * Fraction(3) == Fraction(1)
Out: True
Очевидным ограничением остается то, что иррациональные числа (например, π) все равно будут представлены только в приближенной форме.
👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2💩2
UTF-8 - это кодировка с переменной длиной. Один символ может быть закодирован с использованием одного, двух, трёх или четырёх байтов. Это означает, что нельзя начать чтение строки в кодировке UTF-8 с произвольного байта, так как это может случайно разрушить символ:
Также это означает, что для пропуска первых
Однако можно пропустить фиксированное количество байтов, принимая во внимание некоторые особенности. Вот как может быть закодирован символ в UTF-8:
Как видно, байт является начальным байтом символа, если его вид не совпадает с
Пример использования:
📲 Мы в MAX
👉@BookPython
In : lion = 'Löwe'
In : lion.encode('utf-8')[2:]
Out: b'\xb6we'
In : lion.encode('utf-8')[2:].decode('utf-8')
...
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb6 in position 0: invalid start byte
Также это означает, что для пропуска первых
N символов строки их необходимо прочитать и декодировать. Рассчитать смещение заранее невозможно.Однако можно пропустить фиксированное количество байтов, принимая во внимание некоторые особенности. Вот как может быть закодирован символ в UTF-8:
0xxxxxxx
110xxxxx 10xxxxxx
1110xxxx 10xxxxxx 10xxxxxx
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
Как видно, байт является начальным байтом символа, если его вид не совпадает с
10xxxxxx. Такие байты называются продолжением символа (continuation bytes). Давайте пропустим их:
def cut_bytes(s, n):
result = s.encode('utf-8')[n:]
mask = int('11000000', 2)
conbyte = int('10000000', 2)
while result[0] and result[0] & mask == conbyte:
result = result[1:]
return result.decode('utf-8')
Пример использования:
In : cut_bytes(lion, 2)
Out: 'we'
In : cut_bytes(lion, 1)
Out: 'öwe'
👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Иногда вам нужно запустить блок кода с несколькими контекстными менеджерами. Например:
Начиная с Python 2.7 и 3.1, это можно сделать с помощью одного выражения
До этого можно было использовать функцию
Однако в современных версиях Python эта функция устарела и вызывает предупреждение. Вместо неё рекомендуется использовать более продвинутый инструмент —
Это особенно полезно, когда количество контекстных менеджеров неизвестно заранее.
📲 Мы в MAX
👉@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
Однако в современных версиях Python эта функция устарела и вызывает предупреждение. Вместо неё рекомендуется использовать более продвинутый инструмент —
contextlib.ExitStack. Он позволяет войти в любое количество контекстов в произвольное время, но гарантирует их корректное завершение:
from contextlib import 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
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍1
Когда корутина asyncio хочет остановиться и взаимодействовать с циклом событий (event loop), она использует
Когда корутина ожидает (
Какое значение возвращает
Почему возникает эта ошибка? Как asyncio понимает, что это вы используете
📲 Мы в MAX
👉@BookPython
await obj (или yield from obj до Python 3.6). Объект obj должен быть другой корутиной, объектом asyncio.Future или любым пользовательским объектом, похожим на Future (любой объект, у которого определен метод __await__).
async def coroutine():
await another_coroutine()
async def another_coroutine():
future = asyncio.Future()
await future
loop = asyncio.get_event_loop()
loop.run_until_complete(coroutine())
Когда корутина ожидает (
await) другую корутину, вторая начинает выполняться вместо первой. Если она ожидает третью, то выполняется третья. Это продолжается до тех пор, пока какая-нибудь корутина не ожидает объект Future. Объект Future фактически возвращает значение, и тогда цикл событий (event loop) получает управление.Какое значение возвращает
Future? Оно возвращает сам себя. Можете ли вы напрямую использовать yield для Future? Нет, это внутренняя деталь, о которой вам обычно не нужно беспокоиться.
class Awaitable:
def __await__(self):
future = asyncio.Future()
yield future
# RuntimeError: yield was used
# instead of yield from in task
async def coroutine():
await Awaitable()
loop = asyncio.get_event_loop()
loop.run_until_complete(coroutine())
Почему возникает эта ошибка? Как asyncio понимает, что это вы используете
yield для Future, а не сам Future? Есть простая защита: Future устанавливает внутренний флаг перед тем, как вернуть управление.👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2