CoolPython
4.68K subscribers
20 photos
44 links
Канал об основах Python и хороших практиках разработки. Создаём системность в обрывочных знаниях.

Тем, кто хочет понимать, что пишет!
Download Telegram
Прямо сейчас в голосовом чате с крутыми специалистами по DS и бэку обсуждаем:

🐠 Python фреймворки,
🐠 Асинхронность,
🐠 GPT-3,
🐠 достижения машинного зрения,
🐠 студию Артемия Лебедева 😅,
🐠 версии Python,
🐠 плохой и хороший код.

Присоединяйтесь. Записи не будет)

Кто был, поделитесь, пожалуйста, как вам? Делать еще такие эфиры?
Магические методы

Магические методы Python -- важный элемент синтаксиса языка. В них нет ничего волшебного или тайного, а наоборот, мы постоянно их вызываем, перегружаем и используем в коде.

Давно хотела о них написать вводную и вот авторы канала @it_resume любезно подготовили для нас с вами карточки.

Наслаждайтесь!
Про культуру коммитов

Работаю над куском кода, который опирается на json файл. Файл этот длиной 7к+ строк (только не спрашивайте, как так вышло). И кусок этот одновременно
- сложный
- используется большим количеством пользователей.

И тут из мастера в этот json прилетают изменения. В которых во всем файле пробелы заменены на табы. То есть, дифф слишком большой и отсмотреть глазами не получается. Поправлю, конечно, но досадно -- и небезопасно.

В связи с чем напоминаю, как коммитить (вот, например, хорошая статья от другого автора)

Для меня главное в этом тексте:
Один коммит = одна атомарная задача

И от себя бы еще добавила:
Дифф удобно смотреть ривьюеру

Чтобы этого добиться, перед каждым коммитом нужно отсматривать изменения в каждом файле, которые хотите залить в репо: с помощью git diff или в IDE.

И еще я никогда не делаю

git add .

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

Поделитесь, какие хорошие практики работы с git вы усвоили за время работы?
​​Уже больше часа лежит весь Фейсбук. Вместе с продуктами компании (WhatsApp, Instagram, мессенджером), отвалились даже DNS и страница статусов https://status.fb.com. И может не работать всё то, что опиралось на fb.

Интересно, что случилось.
Вопрос по Python. Как думаете, является ли тип complex составным?
Anonymous Quiz
19%
Это простой тип
36%
Это составной тип
45%
Что такое complex?
Пара фактов о численных типах
(которые вы, возможно, не знали)

Факт 1

В Python есть три встроенных численных типа. Кроме int и float, которыми мы обычно пользуемся, есть еще complex — комплексные числа.

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

Сконструировать комплексное число в Python можно так:

a = complex(2, 1)

или вот так:

a = 2 + 1j

Получится одно и то же.

Факт 2

Все численные типы в Python унаследованы от класса Number. Проверить это можно так:

from numbers import Number

isinstance(1984, Number) #True
isinstance(3.1415926, Number) #True
isinstance(1j, Number) #True

Кстати, сюрприз: bool тоже унаследован от Number:

isinstance(False, Number) #True

Факт 3

Под капотом логический тип — те же числа, только bool имеет всего два значения: 0 и 1. Это обеспечивает нам легкое приведение True к единице, а False к нулю.

Это же, впрочем, дает ни разу не интуитивное поведение в некоторых случаях:

1/False # ZeroDivisionError: division by zero

True * 1 # 1
False * 1 # 0

complex(True, 3.9) # (1+3.9j)

my_list = [1, 2, 3, 4]
my_list[False] # 1

"False"[True] # a

А, и да

Факт 4

Complex не является составным типом. Это просто объект, который принимает до двух параметров при инициализации.

Такие дела!🤗
/ и * в определнии функции

Видели когда-нибудь вот такой синтаксис?

def foo(first, /, second, *, third):
print(first, second, third)


Выглядит странно?

На самом деле / и * навязывают положение ключевых и позиционных аргументов.

Попытаемся, например, вызвать foo() с неправильным набором параметров:

>>> foo("bar", "qux")
...
TypeError: foo() missing 1 required keyword-only argument: 'third'


Нужен keyword аргумент, окей, укажем все параметры:

>>> foo("bar", "baz", "qux")
...
TypeError: foo() takes 2 positional arguments but 3 were given


А, один из них по ключу:

>>> foo("bar", "baz", third="qux")
bar baz qux


Получилось!

Оба символа опциональны. И, в моем опыте, если ставят, то чаще только звездочку.

Источник: https://docs.python.org/3/tutorial/controlflow.html#special-parameters

🐠
Делюсь с вами коллективным учебником по машинному обучению из Яндекса. На самом деле наполовину делюсь, наполовину сохраняю себе, чтобы прочитать позже. Теплый привет Вите Кантору
У нас опять есть группа, можно покомментить и покидаться какашками

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

UPD2 https://t.me/+CgNMmJwzjYI1MmYy
Работа import и структура проекта

Когда вы импортируете какой-то модуль в вашем коде, питон не учитывает, в каком файле этот импорт находится, влияет только то, как был запущен код.
Если модуль не был раньше загружен, питон пытается его найти по очереди в нескольких папках, которые можно посмотреть в переменной sys.path

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

1. Если вы запускаете ваш скрипт командой python scriptname.py, то первым в списке будет тот каталог, где находится запускаемый скрипт. Текущий каталог не имеет значения.
2. Если вы запускаете ваш код командой python -m packagename, то первым в списке будет текущий каталог. При запуске питон попытается найти и импортировать packagename по общим правилам.
3. Если вы запускаете код с помощью других инструментов вроде pytest, они тоже могут сами добавлять что-то в sys.path.

Скорее всего, вам не стоит самостоятельно менять sys.path, так как алгоритм его заполнения стандартный и привычен для всех. Если по каким-то причинам вас он не устраивает, возможно у вас неверная структура проекта.

Так как поиск пакетов для импорта происходит сначала в каталоге "проекта", стоит быть аккуратным именованием ваших файлов и каталогов. Если вы случайно назовете ваш модуль так же как встроенный или сторонний, при любом импорте такого модуля будет грузиться именно ваш, что сломает работу кода.

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

1. Вынести запускаемые скрипты на верхний уровень, а остальной код упаковать в пакет.

Упаковка кода в пакет с уникальным именем позволяет исключить конфликты имен. А вынесение всех запускаемых файлов на один уровень делает состав sys.path предсказуемым.

Выглядеть это будет примерно так:

├── appname
│ ├── __init__.py
│ ├── other_module.py
│ └── some_module.py
├── cli_module.py
└── requirements.txt

2. Создать распространяемый пакет (рекомендую).

В этом случае вы упаковываете весь код в пакет, что помогает исключить конфликты имен.
Для запуска команд вы можете использовать синтаксис python -m appname.cli_module или заполнить секцию entry_points в файле с описанием проекта (setup.cfg, pyproject.toml), после чего иметь свои кастомные консольные команды. В обоих случаях вы сможете запускать код, находясь в любом каталоге, без необходимости указывать полные пути к файлам.

Для удобства разработки с таким подходом удобно устанавливать пакет в editable-режиме с помощью команды типа pip install -e .

Структура будет примерно такой:

├── pyproject.toml
└── src
└── appname
├── __init__.py
├── cli_module.py
├── other_module.py
└── some_module.py

Дополнительные материалы:
* https://packaging.python.org/en/latest/
* https://docs.python.org/3/reference/import.html
* https://docs.python.org/3/library/sys.html#sys.path
* https://ru.wikipedia.org/wiki/Рабочий_каталог
Сегодня в 18:00 UTC+2 релизят Python 3.11 в прямом эфире, смотреть можно по ссылке ниже:

https://www.youtube.com/watch?v=PGZPSWZSkJI

UPD: еще можно подписаться на их youtube, чтобы не пропускать релизы в будущем, если вам интересно