Рубрика #АМужикиТоИНеЗнали на нашем канале демонстрирует необычные и малоизвестные факты о программировании на Python, которые могут удивить даже опытных разработчиков. Это короткие, но мощные порции знаний для тех, кто хочет глубже погрузиться в мир IT и расширить свои горизонты.
Начнём.
Давайте рассмотрим неочевидную функциональность в Python, которая может быть неизвестна даже опытным разработчикам, такую как контекстные менеджеры и их создание с помощью модуля
Контекстные менеджеры в Python используются для обеспечения предварительной и последующей обработки при выполнении блока кода, часто применяются для управления ресурсами. Самый известный пример использования — конструкция
Малоизвестный факт заключается в том, что вы можете создать свой собственный контекстный менеджер с помощью декоратора
Вот пример создания простого контекстного менеджера, который записывает в лог начало и конец выполнения какого-либо действия:
В этом примере контекстный менеджер
#АМужикиТоИНеЗнали
Начнём.
Давайте рассмотрим неочевидную функциональность в Python, которая может быть неизвестна даже опытным разработчикам, такую как контекстные менеджеры и их создание с помощью модуля
contextlib.Контекстные менеджеры в Python используются для обеспечения предварительной и последующей обработки при выполнении блока кода, часто применяются для управления ресурсами. Самый известный пример использования — конструкция
with open(...) as ...:, которая гарантирует закрытие файла после выхода из блока with.Малоизвестный факт заключается в том, что вы можете создать свой собственный контекстный менеджер с помощью декоратора
contextlib.contextmanager. Это может быть полезно, например, для создания блока кода, который требует установки и очистки ресурсов, таких как открытие и закрытие соединения с базой данных.Вот пример создания простого контекстного менеджера, который записывает в лог начало и конец выполнения какого-либо действия:
from contextlib import contextmanager
import time
@contextmanager
def log_block(name):
start_time = time.time()
print(f"Начало выполнения блока '{name}'")
try:
yield # Передать управление в блок with
finally:
end_time = time.time()
print(f"Завершение выполнения блока '{name}'. Время выполнения: {end_time - start_time:.2f} секунд.")
# Пример использования:
with log_block("обработка данных"):
# Здесь размещается код, который вы хотите выполнить
# Например, какая-то тяжелая задача
time.sleep(2) # Имитация долгой операции
В этом примере контекстный менеджер
log_block печатает сообщение при входе в блок и при выходе из него, а также засекает время выполнения кода внутри блока. Это простой пример того, как можно использовать контекстные менеджеры для улучшения читаемости кода и управления ресурсами.#АМужикиТоИНеЗнали
🔥1💩1
#ПервыйКодНаРайоне #фишки #pip
Ребята, давайте разжуем каждый шаг по созданию и публикации вашего пакета в PIP с примерами и кодом.
Шаг 1: Придумай свой проект
Скажем, у тебя есть полезная функция для вычисления дней до Нового Года. Создай папку
Шаг 2: Организуй свой код
Убедись, что структура твоего проекта выглядит так:
В
Шаг 3: Напиши setup.py
В корне твоего проекта (
- name: Это имя твоего пакета. Как ты его зовешь, так он и будет отображаться в PyPI и при установке через pip.
- version: Версия твоего пакета. Важно обновлять ее с каждым значимым обновлением твоего проекта. Следуй принципам семантического версионирования (например, 1.0.0, 1.0.1 для патчей, 1.1.0 для минорных изменений).
- packages: Сюда входят все Python пакеты (каталоги с файлом
- description: Краткое описание того, что делает твой пакет. Это то, что люди увидят в PyPI, когда найдут твой пакет.
- install_requires: Список зависимостей, необходимых для работы твоего пакета. Если твой проект использует другие пакеты, здесь ты перечисляешь их имена (и желательно версии).
Это типа твоей личной карточки. Как когда ты приходишь на новую площадку, ты говоришь: "Эй, я такой-то, вот мои фишки, вот что я умею". Так вот,
Шаг 4: Протестируй свой пакет
В терминале, в корне проекта, запускай:
Убедись, что все работает, создав виртуальное окружение и установив туда пакет.
Шаг 5: Зарегистрируйся на PyPI
Перейди на [PyPI](https://pypi.org/) и зарегистрируй аккаунт.
Шаг 6: Собери свой пакет
В корне проекта запускай:
Это создаст файл
Шаг 7: Загрузи свой пакет
Сначала установи
Затем загрузи пакет:
Тебе нужно будет ввести имя пользователя и пароль от PyPI.
Шаг 8: Поздравляю, ты в игре!
Теперь твой пакет доступен для всех через PIP:
Вот так, ребята, шаг за шагом вы превращаетесь из уличных хулиганов в настоящих кодерских крестных отцов. Творите, пацаны, и пусть весь мир узнает о ваших талантах!
#ПервыйКодНаРайоне #фишки #pip
Ребята, давайте разжуем каждый шаг по созданию и публикации вашего пакета в PIP с примерами и кодом.
Шаг 1: Придумай свой проект
Скажем, у тебя есть полезная функция для вычисления дней до Нового Года. Создай папку
newyear_countdown и внутри нее файл countdown.py:# countdown.py
from datetime import datetime, date
def days_until_newyear():
today = date.today()
newyear = date(today.year + 1, 1, 1)
delta = newyear - today
return delta.days
Шаг 2: Организуй свой код
Убедись, что структура твоего проекта выглядит так:
newyear_countdown/
__init__.py
countdown.py
В
__init__.py можно добавить следующее:from .countdown import days_until_newyear
Шаг 3: Напиши setup.py
В корне твоего проекта (
newyear_countdown/) создай файл setup.py:from setuptools import setup, find_packages
setup(
name='newyear_countdown', # имя твоего пакета, как ты зовешь свой проект
version='0.1', # версия твоего пакета, чтобы все знали, насколько он свежий
packages=find_packages(), # автоматически находит все пакеты (папки с __init__.py), которые нужно включить
description='Countdown to New Year', # краткое описание твоего проекта, что он делает
install_requires=[], # список зависимостей, других пакетов, без которых твой не будет работать
)
- name: Это имя твоего пакета. Как ты его зовешь, так он и будет отображаться в PyPI и при установке через pip.
- version: Версия твоего пакета. Важно обновлять ее с каждым значимым обновлением твоего проекта. Следуй принципам семантического версионирования (например, 1.0.0, 1.0.1 для патчей, 1.1.0 для минорных изменений).
- packages: Сюда входят все Python пакеты (каталоги с файлом
__init__.py), которые должны быть включены в дистрибутив. find_packages() автоматически находит все такие пакеты в твоем проекте.- description: Краткое описание того, что делает твой пакет. Это то, что люди увидят в PyPI, когда найдут твой пакет.
- install_requires: Список зависимостей, необходимых для работы твоего пакета. Если твой проект использует другие пакеты, здесь ты перечисляешь их имена (и желательно версии).
Это типа твоей личной карточки. Как когда ты приходишь на новую площадку, ты говоришь: "Эй, я такой-то, вот мои фишки, вот что я умею". Так вот,
setup.py – это твоя карточка для Python сообщества.Шаг 4: Протестируй свой пакет
В терминале, в корне проекта, запускай:
python setup.py install
Убедись, что все работает, создав виртуальное окружение и установив туда пакет.
Шаг 5: Зарегистрируйся на PyPI
Перейди на [PyPI](https://pypi.org/) и зарегистрируй аккаунт.
Шаг 6: Собери свой пакет
В корне проекта запускай:
python setup.py sdist
Это создаст файл
.tar.gz в папке dist/.Шаг 7: Загрузи свой пакет
Сначала установи
twine:pip install twine
Затем загрузи пакет:
twine upload dist/*
Тебе нужно будет ввести имя пользователя и пароль от PyPI.
Шаг 8: Поздравляю, ты в игре!
Теперь твой пакет доступен для всех через PIP:
pip install newyear_countdown
Вот так, ребята, шаг за шагом вы превращаетесь из уличных хулиганов в настоящих кодерских крестных отцов. Творите, пацаны, и пусть весь мир узнает о ваших талантах!
#ПервыйКодНаРайоне #фишки #pip
PyPI
PyPI · The Python Package Index
The Python Package Index (PyPI) is a repository of software for the Python programming language.
💩1
#АМужикиТоИНеЗнали
Давайте рассмотрим пример использования распаковки списков с помощью звездочки
Представим, что у вас есть список друзей с района, и вы хотите собрать их всех в одном месте, чтобы устроить вечеринку. У вас уже есть список с некоторыми именами, и вы хотите добавить еще несколько друзей в этот список.
Вот ваш текущий список друзей:
Теперь представим, что вы встретили еще трех других друзей, и вы хотите добавить их к уже существующему списку. Ваши новые друзья:
Чтобы объединить эти два списка в один, вы можете использовать распаковку с помощью
В результате получится следующий список:
Это очень удобный способ объединения списков без необходимости использовать циклы или дополнительные методы. Таким образом, вы можете легко собрать всех друзей вместе.
#АМужикиТоИНеЗнали
Давайте рассмотрим пример использования распаковки списков с помощью звездочки
* на понятном и простом примере.Представим, что у вас есть список друзей с района, и вы хотите собрать их всех в одном месте, чтобы устроить вечеринку. У вас уже есть список с некоторыми именами, и вы хотите добавить еще несколько друзей в этот список.
Вот ваш текущий список друзей:
друзья_с_района = ["Вася", "Петя", "Коля"]
Теперь представим, что вы встретили еще трех других друзей, и вы хотите добавить их к уже существующему списку. Ваши новые друзья:
новые_друзья = ["Лена", "Оля", "Саша"]
Чтобы объединить эти два списка в один, вы можете использовать распаковку с помощью
*, как показано ниже:все_друзья = [*друзья_с_района, *новые_друзья]
В результате получится следующий список:
["Вася", "Петя", "Коля", "Лена", "Оля", "Саша"]
Это очень удобный способ объединения списков без необходимости использовать циклы или дополнительные методы. Таким образом, вы можете легко собрать всех друзей вместе.
#АМужикиТоИНеЗнали
💩1
#АМужикиТоИНеЗнали
Давайте рассмотрим пример использования блока
Представьте, что вы и ваши друзья с района решили сыграть в игру на удачу. Вы кидаете кубик (шестигранный), и если кто-то из вас выбросит шестерку, то этот человек выигрывает и игра заканчивается. Если же никто не выбросит шестерку после нескольких попыток, то все проиграли и решаете попробовать снова позже.
В коде на Python это можно реализовать так:
В этом примере, блок
Использование
#АМужикиТоИНеЗнали
Давайте рассмотрим пример использования блока
else с циклами в Python на понятном примере.Представьте, что вы и ваши друзья с района решили сыграть в игру на удачу. Вы кидаете кубик (шестигранный), и если кто-то из вас выбросит шестерку, то этот человек выигрывает и игра заканчивается. Если же никто не выбросит шестерку после нескольких попыток, то все проиграли и решаете попробовать снова позже.
В коде на Python это можно реализовать так:
from random import randint
попытки = 5 # Допустим, у вас есть 5 попыток
for _ in range(попытки):
бросок = randint(1, 6) # Кидаем кубик
print(f"Бросок: {бросок}")
if бросок == 6:
print("Выигрыш! Кто-то выбросил шестерку!")
break
else: # Этот блок выполнится, если цикл завершился нормально, без 'break'
print("Проигрыш. Никто не выбросил шестерку. Попробуем в другой раз.")
В этом примере, блок
else срабатывает только если цикл for завершился полностью, без прерывания через break. То есть, если никто не выбросил шестерку после всех попыток, выведется сообщение о проигрыше. Если же кто-то выбросил шестерку (и цикл был прерван командой break), блок else не выполняется, и выводится сообщение о выигрыше.Использование
else с циклами может быть не очень интуитивным, но оно может добавить дополнительную логику обработки ситуаций, когда цикл завершился без прерывания.#АМужикиТоИНеЗнали
💩1
#АМужикиТоИНеЗнали
Так как среди читательниц канала есть девушки довольно хорошо владеющие языком программирования Питон, и удивить их сложно, мы всё равно попробуем. Используем метаклассы.
📱
В этом примере метакласс CongratulateMeta автоматически добавляет метод congratulate к любому классу, который его использует. Этот метод выводит персонализированное поздравление, используя имя, определенное в классе.
#АМужикиТоИНеЗнали
Так как среди читательниц канала есть девушки довольно хорошо владеющие языком программирования Питон, и удивить их сложно, мы всё равно попробуем. Используем метаклассы.
class CongratulateMeta(type):
def __new__(cls, name, bases, attrs):
# Добавляем метод для поздравления
attrs['congratulate'] = lambda self: f"Дорогая {attrs['name']}, поздравляем тебя с 8 Марта! Желаем счастья, здоровья и кода без багов везде там, где это действительно необходимо!"
return super().__new__(cls, name, bases, attrs)
# Используем метакласс в определении нового класса
class FemaleProgrammer(metaclass=CongratulateMeta):
name = "Ася"
# Создаем экземпляр класса
programmer = FemaleProgrammer()
print(programmer.congratulate())
Дорогая Ася, поздравляем тебя с 8 Марта! Желаем счастья, здоровья и кода без багов везде там, где это действительно необходимо!
В этом примере метакласс CongratulateMeta автоматически добавляет метод congratulate к любому классу, который его использует. Этот метод выводит персонализированное поздравление, используя имя, определенное в классе.
#АМужикиТоИНеЗнали
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1💩1
#ПервыйКодНаРайоне
Пацаны, вот коротко о том, чем круты виртуальные окружения в Python, как они работают и зачем вам это нужно.
Виртуальное окружение: закрытая тусовка для твоего кода
Считай, виртуальное окружение – это твоя личная зона для проекта, отделенная от всего мира. Как закрытая вечеринка, где ты контролируешь все: музыку (версию Python), закуски (библиотеки и пакеты) и гостей (зависимости).
Создаем окружение:
Так ты говоришь Python: "Создай мне место, где я буду шеф".
Общепринятно, и мы рекомендуем использовать названия типа
Заходим на тусовку (активируем окружение):
- На Unix или macOS:
- На Windows:
Теперь ты в своем мире, где можешь делать что хочешь, не ломая глобальное пространство.
Покидаем тусовку (деактивируем окружение):
Ты вернулся в реальный мир, где всё как было.
Что тут круто:
Пацаны, давайте разберемся, почему виртуальные окружения в Python – это чистый кайф для каждого кодера:
Наследование от глобального окружения
Смотрите, когда вы создаете новую закрытую тусовку (виртуальное окружение), она не начинается с нуля. Она "наследует" некоторые базовые штуки из вашего большого мира (глобального окружения Python). Это значит, что основные инструменты уже будут под рукой, но без всей той лишней фигни, которая могла накопиться в вашей системе. Это как если бы на вашей вечеринке уже были газировка и чипсы, но музыка и народ – только те, кого вы пригласили.
Изоляция ресурсов
Тут дело такое – каждая ваша тусовка, каждый проект в своем виртуальном окружении, живет своей жизнью. Установили кучу пакетов в одном проекте? Они не попадут в другие. Это помогает избежать конфликтов между зависимостями разных проектов. То есть, если в одном проекте тебе нужна одна версия библиотеки, а в другом – другая, то ты можешь спокойно использовать обе, и они не будут мешать друг другу. Это как иметь разные комнаты для разных тусовок в одном большом доме.
Оптимизация работы с помощью .pth файлов
Допустим, у тебя есть две тусовки: одна – это твой основной проект, а вторая – это такой сайд-проект, где ты экспериментируешь с новыми фишками. Оба проекта используют некие общие файлы, скажем, твои крутые утилиты, которые ты сам написал и хочешь использовать в обоих местах. Эти утилиты лежат в какой-то отдельной папке на твоем компе, скажем
Обычно, если бы ты хотел использовать эти утилиты в обоих проектах, тебе пришлось бы копировать их в каждый проект отдельно. Но это ж гемор, правильно? Каждый раз, когда ты обновляешь утилиты, тебе нужно заменять их в двух местах. Но тут на помощь приходят
Создай файл с расширением
Теперь Python будет знать, что ему нужно искать твои утилиты именно там, и ты сможешь использовать их в обоих проектах, не копируя в каждый. Это как если бы у тебя в каждой тусовке был проход в закрытую комнату, где хранятся твои лучшие напитки, и тебе не нужно каждый раз таскать их с собой.
Виртуальные окружения и интерпретаторы Python
И вот самое главное – каждая твоя тусовка может крутить свою музыку. В мире Python это значит, что каждое виртуальное окружение может использовать свою версию интерпретатора. Это как если бы в каждой комнате твоего дома играла своя музыка – и всем нравится. Это дает тебе свободу экспериментировать и использовать разные версии Python для разных проектов без риска запутаться.
Так что, ребята, виртуальные окружения – это не просто круто, это ваш инструмент для порядка, безопасности и свободы в мире кодинга. Пользуйтесь на здоровье!
#ПервыйКодНаРайоне
Пацаны, вот коротко о том, чем круты виртуальные окружения в Python, как они работают и зачем вам это нужно.
Виртуальное окружение: закрытая тусовка для твоего кода
Считай, виртуальное окружение – это твоя личная зона для проекта, отделенная от всего мира. Как закрытая вечеринка, где ты контролируешь все: музыку (версию Python), закуски (библиотеки и пакеты) и гостей (зависимости).
Создаем окружение:
python -m venv название_для_тусовки
Так ты говоришь Python: "Создай мне место, где я буду шеф".
Общепринятно, и мы рекомендуем использовать названия типа
venv или envЗаходим на тусовку (активируем окружение):
- На Unix или macOS:
source <название_для_тусовки>/bin/activate
- На Windows:
<название_для_тусовки>\Scripts\activate
Теперь ты в своем мире, где можешь делать что хочешь, не ломая глобальное пространство.
Покидаем тусовку (деактивируем окружение):
deactivate
Ты вернулся в реальный мир, где всё как было.
Что тут круто:
Пацаны, давайте разберемся, почему виртуальные окружения в Python – это чистый кайф для каждого кодера:
Наследование от глобального окружения
Смотрите, когда вы создаете новую закрытую тусовку (виртуальное окружение), она не начинается с нуля. Она "наследует" некоторые базовые штуки из вашего большого мира (глобального окружения Python). Это значит, что основные инструменты уже будут под рукой, но без всей той лишней фигни, которая могла накопиться в вашей системе. Это как если бы на вашей вечеринке уже были газировка и чипсы, но музыка и народ – только те, кого вы пригласили.
Изоляция ресурсов
Тут дело такое – каждая ваша тусовка, каждый проект в своем виртуальном окружении, живет своей жизнью. Установили кучу пакетов в одном проекте? Они не попадут в другие. Это помогает избежать конфликтов между зависимостями разных проектов. То есть, если в одном проекте тебе нужна одна версия библиотеки, а в другом – другая, то ты можешь спокойно использовать обе, и они не будут мешать друг другу. Это как иметь разные комнаты для разных тусовок в одном большом доме.
Оптимизация работы с помощью .pth файлов
Допустим, у тебя есть две тусовки: одна – это твой основной проект, а вторая – это такой сайд-проект, где ты экспериментируешь с новыми фишками. Оба проекта используют некие общие файлы, скажем, твои крутые утилиты, которые ты сам написал и хочешь использовать в обоих местах. Эти утилиты лежат в какой-то отдельной папке на твоем компе, скажем
D:\МоиУтилитыОбычно, если бы ты хотел использовать эти утилиты в обоих проектах, тебе пришлось бы копировать их в каждый проект отдельно. Но это ж гемор, правильно? Каждый раз, когда ты обновляешь утилиты, тебе нужно заменять их в двух местах. Но тут на помощь приходят
.pth файлы.Создай файл с расширением
.pth, скажем мои_утилиты.pth, и положи его в папку site-packages, которая находится в твоем виртуальном окружении (это как VIP-зона каждой из твоих тусовок). В этом файле просто укажи путь к папке с твоими утилитами D:\МоиУтилиты
Теперь Python будет знать, что ему нужно искать твои утилиты именно там, и ты сможешь использовать их в обоих проектах, не копируя в каждый. Это как если бы у тебя в каждой тусовке был проход в закрытую комнату, где хранятся твои лучшие напитки, и тебе не нужно каждый раз таскать их с собой.
Виртуальные окружения и интерпретаторы Python
И вот самое главное – каждая твоя тусовка может крутить свою музыку. В мире Python это значит, что каждое виртуальное окружение может использовать свою версию интерпретатора. Это как если бы в каждой комнате твоего дома играла своя музыка – и всем нравится. Это дает тебе свободу экспериментировать и использовать разные версии Python для разных проектов без риска запутаться.
Так что, ребята, виртуальные окружения – это не просто круто, это ваш инструмент для порядка, безопасности и свободы в мире кодинга. Пользуйтесь на здоровье!
#ПервыйКодНаРайоне
❤1👍1💩1
#ПервыйКодНаРайоне
Братва, сегодня мы зайдем с вами в мир Python с другой стороны улицы – поговорим о магических методах. Это не просто какие-то функции, это настоящая магия в мире кода, которая позволяет нашим объектам (ссыль для самых продвинутых из вас) вести себя как настоящие шулеры в карточной игре.
Магические методы в Python – это спецфункции, благодаря которым твой код начинает работать по-новому, становится более крутым и умным. Как невидимые нити, они позволяют объектам взаимодействовать друг с другом и с Python'ом на глубоком уровне.
Давайте напишем простой код, который кое что растолкует сам по себе:
Теперь подробнее:
Магические методы - это такие функции, которые начинаются и заканчиваются двойными подчеркиваниями, типа
-
-
-
-
-
Этот простой пример показывает основы магических методов, мы еще будем рассматривать их подробнее, как это делается в некоторых крутых книгах, которые мы обязательно тут разыграем. "Не переключайтесь!"
#ПервыйКодНаРайоне
Братва, сегодня мы зайдем с вами в мир Python с другой стороны улицы – поговорим о магических методах. Это не просто какие-то функции, это настоящая магия в мире кода, которая позволяет нашим объектам (ссыль для самых продвинутых из вас) вести себя как настоящие шулеры в карточной игре.
Магические методы в Python – это спецфункции, благодаря которым твой код начинает работать по-новому, становится более крутым и умным. Как невидимые нити, они позволяют объектам взаимодействовать друг с другом и с Python'ом на глубоком уровне.
Давайте напишем простой код, который кое что растолкует сам по себе:
import collections
from random import choice, shuffle
# Создаём картеж для карт, чтобы каждая карта была как уникальный элемент с рангом и мастью.
Card = collections.namedtuple('Card', ['ранг', 'масть'])
class FrenchDeck:
# Определяем ранги карт и масти в виде юникод символов.
ranks = [str(n) for n in range(2, 11)] + list('JQKA')
suits = '♠️ ♦️ ♣️ ♥️'.split()
def __init__(self):
# Заполняем нашу новенькую колоду картами, создаём рангами и мастями.
self._cards = [Card(rank, suit) for suit in self.suits for rank in self.ranks]
def __len__(self):
# Возвращает количество карт в колоде чтобы лохи верили, что мы не шулеры.
return len(self._cards)
def __getitem__(self, position):
# Получение карты из колоды по её позиции - как звонок определённому жителю города.
return self._cards[position]
def __setitem__(self, position, value):
# Меняем карту в колоде - это как переезд жителя на новое место.
self._cards[position] = value
def __repr__(self):
# Представление колоды карт для печати. Покажет всех "жителей" нашего города.
return f'FrenchDeck({self._cards})'
crime_queen = Card('Q', '♠️') # Пример карты - "Пиковая дама". (Коварна и упряма)
print(crime_queen)
deck = FrenchDeck() # Создаём колоду карт.
print(f'{len(deck)=}') # Узнаём количество карт в колоде.
print(f'{deck[0]=}') # Показываем первую карту в колоде.
print(f'{deck[-1]=}') # Показываем последнюю карту в колоде.
print(f'{choice(deck)=}') # Выбираем случайную карту из колоды.
shuffle(deck) # Перемешиваем карты в колоде.
for d in deck:
print(d) # Выводим всю колоду на печать.
Теперь подробнее:
Магические методы - это такие функции, которые начинаются и заканчиваются двойными подчеркиваниями, типа
__такие__. Эти методы позволяют тебе определить поведение твоих классов (объектов) на внешние предъявы и вопросы. Например в случае с нашей шуллерской колодой:-
__init__ в классе FrenchDeck: Здесь ты создаешь колоду карт. Это как когда ты открываешь новую пачку игральных карт – расставляешь все по порядку.-
__len__ в FrenchDeck: Спроси "Сколько карт в колоде, брат?" – и этот метод ответит тебе, сколько карт в твоей колоде.-
__getitem__ в FrenchDeck: Это как выбрать одну карту из колоды. Скажешь deck[0], получишь верхнюю карту, скажешь deck[-1], получишь самую последнюю.-
__setitem__ в FrenchDeck: Тут ты уже играешь по-крупному, меняя карты местами, как хитрый шулер. Добавляется, чтобы можно было делать штуки типа перемешивания.-
__repr__ в FrenchDeck: Это как когда ты показываешь всю колоду друзьям, раскладывая перед ними. Дает полное представление о том, что в колоде.Этот простой пример показывает основы магических методов, мы еще будем рассматривать их подробнее, как это делается в некоторых крутых книгах, которые мы обязательно тут разыграем. "Не переключайтесь!"
#ПервыйКодНаРайоне
🔥3👍2💩1
#ПервыйКодНаРайоне Браток, слышал о такой штуке, как ChainMap в Python? Давай разберем на понятиях, чтобы ты понял суть, как на улице разбираются с долгами.
Представь, у тебя есть несколько карманов, в каждом – свои бабки, карточки, записки. Но когда ты ищешь конкретную фишку, типа пятёрку или записку от братвы, тебе не приходится выворачивать все карманы. Ты знаешь, в каком кармане что лежит, но иногда забываешь. Вот здесь на помощь и приходит
Когда ты ищешь что-то через
Но вот беда, если ты решишь что-то добавить через
Допустим, у нас есть братишки из разных районов: Москва, Питер, Казань. У каждого из них своя область ответственности, и тебе нужно все это собрать в кучу, чтобы знать, к кому по каким вопросам обращаться. Используем
Таким образом, используя
Если в разных городах есть братишки с одинаковыми именами,
Давай покажем на примере, чтобы всё было ясно:
Так что, брат, если у тебя в разных группах есть ребята с одним и тем же именем,
Представь, у тебя есть несколько карманов, в каждом – свои бабки, карточки, записки. Но когда ты ищешь конкретную фишку, типа пятёрку или записку от братвы, тебе не приходится выворачивать все карманы. Ты знаешь, в каком кармане что лежит, но иногда забываешь. Вот здесь на помощь и приходит
ChainMap – это как твой личный помощник, который помнит, что где лежит.ChainMap берет несколько словарей (представь, что это твои карманы) и создает одну общую шнягу, где можно искать ключи и значения по всем словарям сразу, но не перемешивая их. Это как если бы у тебя был помощник, который знает, что в одном кармане бабки, в другом – мелочь для автобуса, а в третьем – записки.Когда ты ищешь что-то через
ChainMap, он сначала смотрит в первый словарь (карман), и если там нет нужного – переходит ко второму, и так далее, пока не найдет или не проверит все карманы.Но вот беда, если ты решишь что-то добавить через
ChainMap, это попадет только в первый карман (словарь), так что будь аккуратен, а то потом ищи свои записки по всем карманам.Допустим, у нас есть братишки из разных районов: Москва, Питер, Казань. У каждого из них своя область ответственности, и тебе нужно все это собрать в кучу, чтобы знать, к кому по каким вопросам обращаться. Используем
ChainMap для этого.from collections import ChainMap
# Допустим, у каждого братишки свои связки.
moscow_bro = {'Вася': 'Финансы', 'Петя': 'Улицы'}
piter_bro = {'Коля': 'Концерты', 'Витя': 'Бары'}
kazan_bro = {'Рустам': 'Спорт', 'Ильяс': 'Еда'}
# Соединяем все связки в одну большую с помощью ChainMap.
all_bros = ChainMap(moscow_bro, piter_bro, kazan_bro)
# Теперь можно искать по всем братишкам сразу.
print(all_bros['Вася']) # Финансы
print(all_bros['Коля']) # Концерты
print(all_bros['Рустам']) # Спорт
# Допустим, тебе нужно добавить нового братишку.
all_bros['Дима'] = 'Музыка' # Добавляется в Московскую группу, потому что она первая в ChainMap.
print(moscow_bro) # {'Вася': 'Финансы', 'Петя': 'Улицы', 'Дима': 'Музыка'}
# Проверяем, в каком "городе" какие братишки и их дела.
print(all_bros.maps) # Выведет список словарей, которые в ChainMap.
Таким образом, используя
ChainMap, мы собрали всех братишек под одну крышу, и теперь можем легко найти, кто за что отвечает, и к кому обратиться по тем или иным вопросам.Если в разных городах есть братишки с одинаковыми именами,
ChainMap будет обращаться к первому найденному имени в порядке, в котором ты объединил свои словари (города). Поэтому, если есть одноименные братки, то ответственности братишки из первого словаря (города) будут приоритетнее для ChainMap.Давай покажем на примере, чтобы всё было ясно:
from collections import ChainMap
# Братишки из разных городов.
moscow_bro = {'Вася': 'Финансы', 'Петя': 'Улицы'}
piter_bro = {'Вася': 'Концерты', 'Витя': 'Бары'} # В Питере тоже есть Вася, но он отвечает за концерты.
kazan_bro = {'Рустам': 'Спорт', 'Ильяс': 'Еда'}
# Объединяем всех в ChainMap.
all_bros = ChainMap(moscow_bro, piter_bro, kazan_bro)
# Попробуем найти Васю.
print(all_bros['Вася']) # Выведет 'Финансы' потому что московский Вася в первом словаре, который мы передали в ChainMap.
# Посмотрим, какие данные есть по всем братишкам.
print(all_bros.maps) # Тут можно будет увидеть всех братишек в списке словарей.
# Если нам нужно обратиться к Васе из Питера, нужно пройти через все словари.
for city_bros in all_bros.maps:
if 'Вася' in city_bros:
print(city_bros['Вася']) # Теперь мы увидим ответственности каждого Васи во всех городах.
Так что, брат, если у тебя в разных группах есть ребята с одним и тем же именем,
ChainMap покажет тебе инфу только от первого попавшегося в списке. Но ты всегда можешь обойти все словари вручную, чтобы найти всех одноименников.#ПервыйКодНаРайоне👍1🔥1💩1
#ПервыйКодНаРайоне
Братва, сегодня я вам раскрою тему лямбда-функций в Питоне. Это как когда тебе нужно сделать быструю и маленькую задачку, не разводя длинную авантюру.
Что такое лямбда-функция?
Лямбда-функция в Питоне – это маленькая анонимная функция, у которой может быть куча аргументов, но только одно выражение. Это типа когда ты просишь брата на секунду помочь – быстро и по существу. Анонимная в данном случае означает, что у неё нет имени, и нельзя её просто так взять, и вызвать из другой части кода.
Пример №1: Сортировка списка кортежей
Допустим, у тебя есть список долгов перед братвой, и тебе нужно их отсортировать по размеру долга.
Пример №2: Фильтрация списка
Есть список чуваков, и нужно оставить только тех, у кого в имени есть "а".
Пример №3: Применение функции к списку
У тебя есть список ценников на вещи, и нужно к каждому прибавить НДС.
Так вот, братан, лямбда-функции – это когда надо быстро и без лишних вопросов сделать дело. Они маленькие, но могут пригодиться в самых разных ситуациях.
#ПервыйКодНаРайоне
Братва, сегодня я вам раскрою тему лямбда-функций в Питоне. Это как когда тебе нужно сделать быструю и маленькую задачку, не разводя длинную авантюру.
Что такое лямбда-функция?
Лямбда-функция в Питоне – это маленькая анонимная функция, у которой может быть куча аргументов, но только одно выражение. Это типа когда ты просишь брата на секунду помочь – быстро и по существу. Анонимная в данном случае означает, что у неё нет имени, и нельзя её просто так взять, и вызвать из другой части кода.
Пример №1: Сортировка списка кортежей
Допустим, у тебя есть список долгов перед братвой, и тебе нужно их отсортировать по размеру долга.
dolgi = [('Саня', 100), ('Витя', 50), ('Петя', 75)]
# Используем лямбду для сортировки по второму элементу кортежа (размеру долга)
otvet = sorted(dolgi, key=lambda x: x[1])
print(otvet) # Выведет список отсортированный по размеру долгаПример №2: Фильтрация списка
Есть список чуваков, и нужно оставить только тех, у кого в имени есть "а".
bratva = ['Саня', 'Витя', 'Петя', 'Коля']
# Используем лямбду в фильтре, чтобы оставить только нужных братьев
filter_otvet = list(filter(lambda x: 'а' in x, bratva))
print(filter_otvet) # Покажет тех, у кого есть 'а' в имени
Пример №3: Применение функции к списку
У тебя есть список ценников на вещи, и нужно к каждому прибавить НДС.
cenniki = [100, 200, 300]
# Используем лямбду с map, чтобы к каждому ценнику прибавить НДС
nds_otvet = list(map(lambda x: x * 1.2, cenniki))
print(nds_otvet) # Выведет новые ценники уже с НДС
Так вот, братан, лямбда-функции – это когда надо быстро и без лишних вопросов сделать дело. Они маленькие, но могут пригодиться в самых разных ситуациях.
#ПервыйКодНаРайоне
👍4🔥1💩1
#ПервыйКодНаРайоне
О, братишка, сейчас поговорим про
Что такое
Функция
Примеры использования
Пример №1: Суммирование списка чисел
Допустим, у тебя есть список бабок, которые ты должен взять с братвы, и ты хочешь узнать, сколько всего бабок тебе обещали.
Пример №2: Нахождение максимального числа в списке
Если тебе нужно выбрать самого богатого братана из списка долгов, то
Пример №3: Умножение всех чисел в списке
Ты хочешь узнать, во сколько раз увеличится твой капитал, если каждый день умножать его на какой-то коэффициент.
Вот так, бро,
#ПервыйКодНаРайоне
О, братишка, сейчас поговорим про
reduce. Эта функция в Питоне - как крутой барыга на рынке, который умеет из кучи мелочи делать одну большую котлету. Собирает всё в кучу и выдает тебе финальный результат. Чтобы пользоваться reduce, надо подключить его откуда? Правильно, из модуля functools.Что такое
reduce?Функция
reduce принимает два аргумента: функцию и последовательность. Функция должна быть такой, что принимает два аргумента, а reduce применяет её ко всем элементам списка, шаг за шагом, сокращая список до одного единственного значения. Это как если бы ты складывал деньги в копилку: кидаешь одну монету, потом другую, и так, пока не сложишь всё.Примеры использования
reduceПример №1: Суммирование списка чисел
Допустим, у тебя есть список бабок, которые ты должен взять с братвы, и ты хочешь узнать, сколько всего бабок тебе обещали.
from functools import reduce
# Список бабок
babki = [100, 200, 300, 400]
# Функция для суммирования
def summa(x, y):
return x + y
# Используем reduce для суммирования
total_babki = reduce(summa, babki)
print(total_babki) # Выведет 1000
Пример №2: Нахождение максимального числа в списке
Если тебе нужно выбрать самого богатого братана из списка долгов, то
reduce поможет и с этим.# Список долгов братвы
dolgi = [100, 200, 500, 300]
# Функция для нахождения максимума
def max_dolg(x, y):
return x if x > y else y
# Используем reduce для нахождения максимального долга
max_dolg = reduce(max_dolg, dolgi)
print(max_dolg) # Выведет 500
Пример №3: Умножение всех чисел в списке
Ты хочешь узнать, во сколько раз увеличится твой капитал, если каждый день умножать его на какой-то коэффициент.
# Коэффициенты роста капитала за 4 дня
coefficients = [1.1, 1.2, 1.3, 1.4]
# Функция для умножения
def umnozhit(x, y):
return x * y
# Используем reduce для расчета итогового увеличения
total_growth = reduce(umnozhit, coefficients)
print(f"Капитал увеличится в {total_growth:.2f} раз") # Форматируем вывод, чтобы было красиво
Вот так, бро,
reduce работает как зверь, когда дело доходит до объединения всего в одно целое. На улицах это как собрать всю братву для большой тусы: по одному они мало что могут, а вместе - сила.#ПервыйКодНаРайоне
👍3💩1
#Асинхронность на питоне — это как когда у тебя много дел, и ты хочешь все успеть, но времени в обрез. Представь, ты на районе, и у тебя куча дел: надо закинуть вещи в стиралку, сварить макароны и ответить корешу в телеге. В идеале ты бы хотел делать это всё одновременно, чтобы не тратить время зря.
Так вот, в программировании тоже самое. У тебя есть задачи, которые могут долго выполняться, например, запрос на сервер или чтение файла. Если выполнять их последовательно, ты будешь сидеть и ждать каждую задачу, как будто в очереди за шаурмой.
Асинхронность позволяет запускать задачи параллельно, как будто у тебя несколько рук. В Python это делается с помощью ключевых слов
Вот как это выглядит на коде:
Что происходит в этом коде:
1. Ты запускаешь все три задачи параллельно с
2. Пока стиралка работает, ты можешь заняться макаронами.
3. И пока вода закипает, ты можешь ответить корешу.
Вместо того чтобы ждать, пока каждая задача выполнится, ты используешь своё время эффективно, как настоящий мастер тайм-менеджмента на районе. Асинхронность в Python — это как будто у тебя суперспособности делать всё и сразу, не тратя время на ожидание.
Так вот, в программировании тоже самое. У тебя есть задачи, которые могут долго выполняться, например, запрос на сервер или чтение файла. Если выполнять их последовательно, ты будешь сидеть и ждать каждую задачу, как будто в очереди за шаурмой.
Асинхронность позволяет запускать задачи параллельно, как будто у тебя несколько рук. В Python это делается с помощью ключевых слов
async и await.Вот как это выглядит на коде:
import asyncio
async def стиралка():
print("Закинул вещи в стиралку...")
await asyncio.sleep(5) # стиралка работает
print("Вещи постираны!")
async def макароны():
print("Поставил воду на макароны...")
await asyncio.sleep(3) # вода закипает
print("Макароны сварены!")
async def отвечаю_корешу():
print("Ответил корешу в телеге...")
await asyncio.sleep(1) # печатаешь сообщение
print("Сообщение отправлено!")
async def главный_план():
await asyncio.gather(стиралка(), макароны(), отвечаю_корешу())
# Запуск программы
asyncio.run(главный_план())
Что происходит в этом коде:
1. Ты запускаешь все три задачи параллельно с
asyncio.gather().2. Пока стиралка работает, ты можешь заняться макаронами.
3. И пока вода закипает, ты можешь ответить корешу.
Вместо того чтобы ждать, пока каждая задача выполнится, ты используешь своё время эффективно, как настоящий мастер тайм-менеджмента на районе. Асинхронность в Python — это как будто у тебя суперспособности делать всё и сразу, не тратя время на ожидание.
👏4💩1
Братва, давайте обсудим, когда нужно профилировать работу кода и какие инструменты у нас для этого есть. Это как проверка твоей тачки на сервисе: ты хочешь знать, где у тебя пробелы, что можно улучшить и где ускориться, чтобы гонять еще быстрее.
Когда нужно профилировать код?
Профилирование нужно, когда:
1. Код работает медленно: Если твой код выполняется дольше, чем ты ожидал, профилирование поможет найти узкие места.
2. Большое потребление ресурсов: Если программа жрет слишком много памяти или процессорного времени.
3. Неоптимальные алгоритмы: Когда тебе кажется, что можно оптимизировать алгоритмы, но не знаешь, где именно.
4. Проверка производительности: После внесения изменений или рефакторинга нужно убедиться, что все стало работать не хуже, а лучше.
Инструменты для профилирования
Есть несколько крутых инструментов, которые помогут тебе понять, где твой код тормозит и как это исправить.
1.
Пример использования
Этот код покажет тебе подробный отчет о времени выполнения каждой части твоего кода.
2.
Пример использования
Этот код покажет тебе, какой вариант выполняется быстрее.
3.
Пример использования
Запусти этот код и увидишь, как используется память в каждом участке функции.
Профилирование — это как техосмотр твоей тачки. Ты хочешь знать, где у тебя слабые места, и что можно подтянуть, чтобы все работало как часы. Используй
Когда нужно профилировать код?
Профилирование нужно, когда:
1. Код работает медленно: Если твой код выполняется дольше, чем ты ожидал, профилирование поможет найти узкие места.
2. Большое потребление ресурсов: Если программа жрет слишком много памяти или процессорного времени.
3. Неоптимальные алгоритмы: Когда тебе кажется, что можно оптимизировать алгоритмы, но не знаешь, где именно.
4. Проверка производительности: После внесения изменений или рефакторинга нужно убедиться, что все стало работать не хуже, а лучше.
Инструменты для профилирования
Есть несколько крутых инструментов, которые помогут тебе понять, где твой код тормозит и как это исправить.
1.
cProfilecProfile — это встроенный в Питон модуль для профилирования. Он покажет тебе, сколько времени занимает каждая функция.Пример использования
cProfileimport cProfile
def main():
# Твой код здесь
total = 0
for i in range(1000000):
total += i
print(total)
cProfile.run('main()')
Этот код покажет тебе подробный отчет о времени выполнения каждой части твоего кода.
2.
timeittimeit — это модуль для измерения времени выполнения небольших участков кода. Он полезен, когда тебе нужно проверить, какой из двух фрагментов кода работает быстрее.Пример использования
timeitimport timeit
# Первый вариант кода
setup_code = "from math import sqrt"
test_code_1 = """
def compute():
result = []
for i in range(100):
result.append(sqrt(i))
return result
"""
# Второй вариант кода
test_code_2 = """
def compute():
return [sqrt(i) for i in range(100)]
"""
time_1 = timeit.timeit(setup=setup_code, stmt=test_code_1, number=10000)
time_2 = timeit.timeit(setup=setup_code, stmt=test_code_2, number=10000)
print(f"Время первого варианта: {time_1}")
print(f"Время второго варианта: {time_2}")
Этот код покажет тебе, какой вариант выполняется быстрее.
3.
memory_profilermemory_profiler — это инструмент для отслеживания использования памяти твоим кодом. Он поможет найти места, где память тратится впустую.Пример использования
memory_profilerfrom memory_profiler import profile
@profile
def main():
a = [i for i in range(100000)]
b = [x * 2 for x in a]
del a
return b
if __name__ == '__main__':
main()
Запусти этот код и увидишь, как используется память в каждом участке функции.
Профилирование — это как техосмотр твоей тачки. Ты хочешь знать, где у тебя слабые места, и что можно подтянуть, чтобы все работало как часы. Используй
cProfile для общего профилирования, timeit для проверки времени выполнения небольших фрагментов кода и memory_profiler для отслеживания потребления памяти. Так ты всегда будешь на коне и твой код будет летать как ракета!👍4💩1
Окей, братва, сейчас я вам расскажу про модули в Питоне и как использовать файл
Что такое модуль?
Модуль в Питоне — это просто файл с кодом, который ты можешь импортировать и использовать в других частях своей программы. Например, у тебя есть файл
Что такое пакет?
Пакет — это как набор модулей, собранных в одну папку. Пакет позволяет структурировать код, делая его организованным и удобным для навигации. Чтобы Питон понял, что папка является пакетом, в ней должен быть файл
Создание пакета
Допустим, у тебя есть проект с такой структурой:
Ты можешь организовать их в пакет:
Что такое `__init__.py`?
Пример использования `__init__.py`
Давайте сделаем так, чтобы наш пакет
Теперь ты можешь импортировать функции прямо из пакета:
Фишки с `__init__.py`
1. Удобный импорт
Ты можешь упростить импорт, собирая все нужные функции и классы в
Теперь импорт будет выглядеть еще проще:
2. Инициализация пакета
Ты можешь выполнять код при загрузке пакета, например, устанавливать конфигурации или проверять зависимости.
3. Подпакеты и вложенные пакеты
Если у тебя сложная структура проекта, ты можешь иметь вложенные пакеты:
В
4. Динамическая загрузка модулей
Ты можешь динамически загружать модули в зависимости от условий:
Заключение
Пакеты и модули помогают тебе держать код в порядке, как на районе. Файл
__init__.py с фишками. Это как уметь управлять своим районом: знать, где кто живет, как всех организовать и сделать так, чтобы всё работало четко и гладко.Что такое модуль?
Модуль в Питоне — это просто файл с кодом, который ты можешь импортировать и использовать в других частях своей программы. Например, у тебя есть файл
math_functions.py, где ты хранишь все свои математические функции. Этот файл и есть модуль.# math_functions.py
def add(x, y):
return x + y
def subtract(x, y):
return x - y
Что такое пакет?
Пакет — это как набор модулей, собранных в одну папку. Пакет позволяет структурировать код, делая его организованным и удобным для навигации. Чтобы Питон понял, что папка является пакетом, в ней должен быть файл
__init__.py.Создание пакета
Допустим, у тебя есть проект с такой структурой:
my_project/
math_functions.py
string_functions.py
Ты можешь организовать их в пакет:
my_project/
my_package/
__init__.py
math_functions.py
string_functions.py
Что такое `__init__.py`?
__init__.py — это специальный файл, который позволяет Питону понимать, что эта папка является пакетом. Он может быть пустым, но обычно в нем можно описать код, который должен выполняться при импорте пакета.Пример использования `__init__.py`
Давайте сделаем так, чтобы наш пакет
my_package автоматически импортировал все функции из своих модулей. Вот как может выглядеть __init__.py:# my_project/my_package/__init__.py
from .math_functions import add, subtract
from .string_functions import uppercase, lowercase
Теперь ты можешь импортировать функции прямо из пакета:
# main.py
from my_package import add, uppercase
print(add(2, 3)) # Выведет 5
print(uppercase('hello')) # Выведет HELLO
Фишки с `__init__.py`
1. Удобный импорт
Ты можешь упростить импорт, собирая все нужные функции и классы в
__init__.py, чтобы не писать длинные пути при импорте.# my_project/my_package/__init__.py
from .math_functions import add, subtract
from .string_functions import uppercase, lowercase
__all__ = ['add', 'subtract', 'uppercase', 'lowercase']
Теперь импорт будет выглядеть еще проще:
from my_package import *
2. Инициализация пакета
Ты можешь выполнять код при загрузке пакета, например, устанавливать конфигурации или проверять зависимости.
# my_project/my_package/__init__.py
print("Загружается пакет my_package")
# Инициализация настроек
config = {
'setting_1': True,
'setting_2': 'default_value'
}
3. Подпакеты и вложенные пакеты
Если у тебя сложная структура проекта, ты можешь иметь вложенные пакеты:
my_project/
my_package/
__init__.py
math_functions.py
string_functions.py
sub_package/
__init__.py
helper_functions.py
В
__init__.py пакета sub_package можно описывать импорт функций из вложенного пакета:# my_project/my_package/sub_package/__init__.py
from .helper_functions import helper_function
4. Динамическая загрузка модулей
Ты можешь динамически загружать модули в зависимости от условий:
# my_project/my_package/__init__.py
import os
if os.getenv('USE_ADVANCED_FUNCTIONS') == '1':
from .advanced_math_functions import advanced_add
else:
from .basic_math_functions import basic_add as add
Заключение
Пакеты и модули помогают тебе держать код в порядке, как на районе. Файл
__init__.py делает пакет мощным инструментом, позволяя управлять импортом, инициализацией и организацией кода. Используй эти фишки, чтобы твой проект был четким и организованным, как элитный район.👍8🥰1💩1
Йо, пацаны, сегодня про важное! 😎🐍
Знаете, что такое GIL? Это такой "Главный Интерпретаторский Замок", который держит ваш Питон в узде, пока он шпарит код в одном потоке. Но вот что интересно — в новом Питоне 3.13 чуваки из Python решили, что можно и без этого замка жить. Казалось бы, свобода для всех потоков, но тут есть засада!
🔥 Если ты компилишь Python без GIL и запускаешь один поток — привет, тормоза! Почему? Ну, потому что система теперь тратит время на то, чтобы сделать всё безопасным для многопоточности. В итоге твой код тормозит примерно на 40% сильнее, чем в обычной версии с GIL! Да, это как если бы ты снял шлем на гонках и надеялся, что ветер сам разрулит — но нет, тормоза будут!
💡 Когда это важно? Если у тебя обычный код, который не гоняет сотни потоков, то без GIL ты тупо теряешь скорость, как будто тачку на ручник поставил. Free-threaded Питон — штука крутая для тех, кто шарит в многопоточности, но если у тебя один поток, держись подальше, пока не прикрутят норм оптимизации.
🥶 Но есть надежда! Говорят, что в Python 3.14 сделают так, что без GIL код будет тормозить всего на 10%, а это уже не так обидно. Но это потом, а пока — не гоняй, где не надо!
Вывод для пацанов: если твой код одинокий волк (однопоточный), то GIL тебе друг. А если ты хочешь жить на грани и жмешь на газ в многопоточке — пробуй без GIL, но будь готов к тормозам в версии 3.13. 🚗💨
Понравилось? Лайк и подписка, вы ж знаете, куда нажать! 💪
Знаете, что такое GIL? Это такой "Главный Интерпретаторский Замок", который держит ваш Питон в узде, пока он шпарит код в одном потоке. Но вот что интересно — в новом Питоне 3.13 чуваки из Python решили, что можно и без этого замка жить. Казалось бы, свобода для всех потоков, но тут есть засада!
🔥 Если ты компилишь Python без GIL и запускаешь один поток — привет, тормоза! Почему? Ну, потому что система теперь тратит время на то, чтобы сделать всё безопасным для многопоточности. В итоге твой код тормозит примерно на 40% сильнее, чем в обычной версии с GIL! Да, это как если бы ты снял шлем на гонках и надеялся, что ветер сам разрулит — но нет, тормоза будут!
💡 Когда это важно? Если у тебя обычный код, который не гоняет сотни потоков, то без GIL ты тупо теряешь скорость, как будто тачку на ручник поставил. Free-threaded Питон — штука крутая для тех, кто шарит в многопоточности, но если у тебя один поток, держись подальше, пока не прикрутят норм оптимизации.
🥶 Но есть надежда! Говорят, что в Python 3.14 сделают так, что без GIL код будет тормозить всего на 10%, а это уже не так обидно. Но это потом, а пока — не гоняй, где не надо!
Вывод для пацанов: если твой код одинокий волк (однопоточный), то GIL тебе друг. А если ты хочешь жить на грани и жмешь на газ в многопоточке — пробуй без GIL, но будь готов к тормозам в версии 3.13. 🚗💨
Понравилось? Лайк и подписка, вы ж знаете, куда нажать! 💪
GitHub
cpython/Doc/howto/free-threading-python.rst at main · python/cpython
The Python programming language. Contribute to python/cpython development by creating an account on GitHub.
❤3👍2🔥2⚡1💩1
🔥 Продолжаем базарить про Python 3.13! 🔥
В прошлом посте мы уже говорили про те самые 40% потери производительности в однопоточных программах без GIL. Но не всё так плохо, пацаны. Давайте разберём, что ещё нас ждёт в Python 3.13, и как это вообще использовать.
Дата релиза и что это значит для тебя 📅
Python 3.13 выходит уже 7 октября 2024 года! Это значит, что скоро можно будет официально юзать версии без GIL. Это не просто мелкая обнова, это настоящая революция для тех, кто хочет выжимать из многопоточности максимум. Твой код будет реально параллельно работать на всех ядрах процессора, как настоящий чемпион.
Как запустить Free-threading? 🛠
1. Windows и macOS: качай обнову с официального сайта и просто выбирай установку без GIL.
2. Линукс или самосборщики: компилируешь с флагом
Как чекнуть, отключён ли GIL? 🔍
Чтобы убедиться, что ты реально отключил GIL, запускай:
Если увидишь надпись "experimental free-threading build", значит, ты сделал всё по красоте.
Можно ещё проверить в рантайме через функцию
Что по безопасности в многопоточке? ⚠️
Когда работаешь без GIL, стоит быть осторожным:
- Итераторы: не дели один и тот же итератор на все потоки — это может привести к проблемам.
- Frame объекты: не трогай их в других потоках, это может крашнуть программу.
Иммортализация объектов — это чё? 🛡
Теперь некоторые объекты в free-threading режиме становятся бессмертными. Это значит, что они больше не будут удаляться из памяти. Это касается функций, модулей, методов и строк. Учти, если таких объектов будет много, твоя оперативка быстро забьётся. Иными словами - утечка памяти. Но в 3.14 это тоже обещали забороть.
Что по C-расширениям? 🔧
Если твои проекты зависят от C-расширений, знай, что не все из них поддерживают работу без GIL. Если вдруг что, GIL включится автоматически, и ты увидишь предупреждение.
Это касается например таких важных либ, как lxml, на базе которой например сделаны самые быстрые части BeautifulSoup и много чего еще.
Потому твой какой нибудь парсер скорее всего нормально в free-trading 3.13 не заработает, братан.
Но со временем чуваки доработают и этот момент, причем есть шанс что в промежуточных версиях до 3.14 (ноэтонеточно)
Итог: как выжать максимум из Python 3.13? 💪
1. Готовься к многопоточности: вырубай GIL, если твой проект реально нуждается в многопоточности, и кайфуй от полной загрузки всех ядер процессора.
2. Однопоточный код? Подожди 3.14: если твой проект однопоточный, лучше дождись версии Python 3.14, где ребята обещают снизить потери производительности до 10%.
3. Иммортализация объектов: если у тебя много модулей и строк — будь готов к увеличению потребления памяти.
Python 3.13 уже 7 октября 2024! Но использовать его нужно если ты чётко осознаешь последствия!
В прошлом посте мы уже говорили про те самые 40% потери производительности в однопоточных программах без GIL. Но не всё так плохо, пацаны. Давайте разберём, что ещё нас ждёт в Python 3.13, и как это вообще использовать.
Дата релиза и что это значит для тебя 📅
Python 3.13 выходит уже 7 октября 2024 года! Это значит, что скоро можно будет официально юзать версии без GIL. Это не просто мелкая обнова, это настоящая революция для тех, кто хочет выжимать из многопоточности максимум. Твой код будет реально параллельно работать на всех ядрах процессора, как настоящий чемпион.
Как запустить Free-threading? 🛠
1. Windows и macOS: качай обнову с официального сайта и просто выбирай установку без GIL.
2. Линукс или самосборщики: компилируешь с флагом
--disable-gil, и готово! Как чекнуть, отключён ли GIL? 🔍
Чтобы убедиться, что ты реально отключил GIL, запускай:
python -VV
Если увидишь надпись "experimental free-threading build", значит, ты сделал всё по красоте.
Можно ещё проверить в рантайме через функцию
sys._is_gil_enabled()
Что по безопасности в многопоточке? ⚠️
Когда работаешь без GIL, стоит быть осторожным:
- Итераторы: не дели один и тот же итератор на все потоки — это может привести к проблемам.
- Frame объекты: не трогай их в других потоках, это может крашнуть программу.
Иммортализация объектов — это чё? 🛡
Теперь некоторые объекты в free-threading режиме становятся бессмертными. Это значит, что они больше не будут удаляться из памяти. Это касается функций, модулей, методов и строк. Учти, если таких объектов будет много, твоя оперативка быстро забьётся. Иными словами - утечка памяти. Но в 3.14 это тоже обещали забороть.
Что по C-расширениям? 🔧
Если твои проекты зависят от C-расширений, знай, что не все из них поддерживают работу без GIL. Если вдруг что, GIL включится автоматически, и ты увидишь предупреждение.
Это касается например таких важных либ, как lxml, на базе которой например сделаны самые быстрые части BeautifulSoup и много чего еще.
Потому твой какой нибудь парсер скорее всего нормально в free-trading 3.13 не заработает, братан.
Но со временем чуваки доработают и этот момент, причем есть шанс что в промежуточных версиях до 3.14 (ноэтонеточно)
Итог: как выжать максимум из Python 3.13? 💪
1. Готовься к многопоточности: вырубай GIL, если твой проект реально нуждается в многопоточности, и кайфуй от полной загрузки всех ядер процессора.
2. Однопоточный код? Подожди 3.14: если твой проект однопоточный, лучше дождись версии Python 3.14, где ребята обещают снизить потери производительности до 10%.
3. Иммортализация объектов: если у тебя много модулей и строк — будь готов к увеличению потребления памяти.
Python 3.13 уже 7 октября 2024! Но использовать его нужно если ты чётко осознаешь последствия!
👍3🔥3💩1💯1
"Братишки, вот как `builtins` решает ваши проблемы с `input()`"
Чё, пацаны, когда юзаешь питончик, всё круто, пока не надо бахнуть
Кто такой
Короче, как мы будем хакать
Чё мы сделаем: бахнем декоратор и вставим туда замутку с подменой
1. Декорим твою функцию так, чтобы вместо обычного
2. Это всё будет кататься через глобальный объект
3. Мы временно заменим его своим и обратно всё откатим после, чтобы никто и не догадался, что мы мутим.
Пример кода
Как это юзать?
Теперь ты можешь кидать это куда угодно. Надо автоматом влепить значения в
Чё будет:
Скрипт больше не будет сидеть в ожидании, когда ты там что-то вкатишь. Он сам себе всё подставит, как ты задал в декораторе. Нормально, да?
Зачем это нужно?
Ну, представь ты тестируешь функции или автоматизируешь штуки, где на каждое
Важный момент
После того как поработали с подменой, мы всегда возвращаем старый добрый
Резюмирую:
Так что, пацаны, юзайте правильно — и будет вам Python с кайфом.
#декоратор #хак
Чё, пацаны, когда юзаешь питончик, всё круто, пока не надо бахнуть
input(). И тут твой скрипт тормозит на месте и ждёт, пока ты что-то влупишь с клавы, да? Не порядок. Но тут я покажу, как сделать, чтобы input() играл по твоим правилам и вообще не парил мозг. Всё это на базе builtins — самого матерого пацана в питонячей тусовке.Кто такой
builtins?builtins — это как главный босс в Python. Он отвечает за всю стандартную движуху, типа print(), len(), input() и т.д. Его всегда можно вызвать по фасту, даже если ты не подключал его напрямую. Но вот фишка — ты можешь подкрутить его и заставить выполнять твои команды.Короче, как мы будем хакать
input()?Чё мы сделаем: бахнем декоратор и вставим туда замутку с подменой
input(). Смотри:1. Декорим твою функцию так, чтобы вместо обычного
input() скрипт сам подставлял то, что тебе надо.2. Это всё будет кататься через глобальный объект
__builtins__, где input() живёт по дефолту.3. Мы временно заменим его своим и обратно всё откатим после, чтобы никто и не догадался, что мы мутим.
Пример кода
def auto_input(mock_values):
def decorator(func):
def wrapper(*args, **kwargs):
# Сохраняем реальный `input`
original_input = __builtins__.input
# Врубаем наши данные вместо реального инпута
values = iter(mock_values)
__builtins__.input = lambda _: next(values)
# Вызов твоей функции
result = func(*args, **kwargs)
# Возвращаем всё как было
__builtins__.input = original_input
return result
return wrapper
return decorator
Как это юзать?
Теперь ты можешь кидать это куда угодно. Надо автоматом влепить значения в
input() — не вопрос:@auto_input(["значение1", "значение2"])
def my_function():
first = input("Введите первое значение: ")
second = input("Введите второе значение: ")
print(f"Введено: {first}, {second}")
my_function()
Чё будет:
Скрипт больше не будет сидеть в ожидании, когда ты там что-то вкатишь. Он сам себе всё подставит, как ты задал в декораторе. Нормально, да?
Зачем это нужно?
Ну, представь ты тестируешь функции или автоматизируешь штуки, где на каждое
input() забивать свои данные вручную — это как бежать марафон на руках. С этой темой ты упростишь себе жизнь и ускоришь тесты. На продакшн не советую так делать, но для теста или всяких хитрых махинаций — это огонь.Важный момент
После того как поработали с подменой, мы всегда возвращаем старый добрый
input(), иначе можно устроить хаос, и другие функции начнут путаться, как оно вообще работает.Резюмирую:
builtins — это тот парень, которого ты можешь взломать и заставить делать работу по твоему. Главное — делать это по уму, чтобы никто не палил тему. Подменяй input(), рули своим кодом и не давай ему тебя держать в заложниках!Так что, пацаны, юзайте правильно — и будет вам Python с кайфом.
#декоратор #хак
😎6👍3😁2💩2🤮1
👋 *Эй, пацаны и девчата!* Сегодня покажу, как кодить на Python так, чтобы выглядело "чётко" и стильно, как белые кроссы. Берём фишки, чтобы ваш код был не просто норм, а 🔝!
1. Списочные включения 🔥
❌ Не канает:
✅ Как надо:
🎤 *Коммент*: Одной строкой создаем список. Чисто — чики-брики, 👌 и сразу порядок.
2. Генераторы 🚀
❌ Как не стоит:
✅ Как надо:
🎤 *Коммент*: Вместо создания огромного списка берём генератор. Память не жрёт, 💾 особенно если данных много.
3. Распаковка кортежей 💼
❌ Плохо:
✅ Как надо:
🎤 *Коммент*: Одной строкой раскидываем значения по переменным, как надо, а не как в лавке с вещами.
4. enumerate() — не парься с индексом 👀
❌ Сложный путь:
✅ Как надо:
🎤 *Коммент*:
5. Менеджер контекста with 📂
❌ Старый способ:
✅ Как надо:
🎤 *Коммент*:
6. Методы словаря get() и setdefault() 🔑
❌ Долго:
✅ Быстрее:
🎤 *Коммент*: Одной строкой получаем значение. 🤏 Легче понять и экономим символы.
7. Обмен значениями через множественное присваивание 🤝
❌ Лишние шаги:
✅ Как профи:
🎤 *Коммент*: Обмениваем значения без временных переменных, как в обменнике.
8. any() и all() — проверка сразу всех 🕵️♂️
❌ Не оптимально:
✅ Лучше так:
🎤 *Коммент*:
9. f-строки 🎫
❌ Устарело:
✅ Современный подход:
🎤 *Коммент*: f-строки дают возможность вставлять значения прямо в текст. 💬 Быстрее и читаемо.
10. PEP 8 🧑🏫
❌ Как не надо:
✅ Правильно:
🎤 *Коммент*: PEP 8 — это стиль, 👔 порядок и уважение. Если хочешь кодить как профи, придерживайся норм.
Доп. Практики 🛠
- Избегаем изменяемых объектов по умолчанию:
❌ Потенциальная проблема:
✅ Надёжно:
🎤 *Коммент*: Изменяемые значения как дефолты могут привести к багам. 🛑 Лучше использовать
- Обработка ошибок через исключения:
❌ Не оптимально:
✅ Используем try-except:
🎤 *Коммент*: Исключения — это 👌 чистый способ ловить ошибки.
⚡️ *Вот такие дела, ребята! Применяйте эти фишки и пишите не просто рабочий код, а настоящий Python с душой!*
1. Списочные включения 🔥
❌ Не канает:
squares = []
for x in range(10):
squares.append(x ** 2)
✅ Как надо:
squares = [x ** 2 for x in range(10)]
🎤 *Коммент*: Одной строкой создаем список. Чисто — чики-брики, 👌 и сразу порядок.
2. Генераторы 🚀
❌ Как не стоит:
large_list = [x * x for x in range(1000000)]
✅ Как надо:
large_generator = (x * x for x in range(1000000))
🎤 *Коммент*: Вместо создания огромного списка берём генератор. Память не жрёт, 💾 особенно если данных много.
3. Распаковка кортежей 💼
❌ Плохо:
point = (10, 20)
x = point[0]
y = point[1]
✅ Как надо:
x, y = point
🎤 *Коммент*: Одной строкой раскидываем значения по переменным, как надо, а не как в лавке с вещами.
4. enumerate() — не парься с индексом 👀
❌ Сложный путь:
i = 0
for item in items:
print(i, item)
i += 1
✅ Как надо:
for i, item in enumerate(items):
print(i, item)
🎤 *Коммент*:
enumerate() даёт и элемент, и индекс. Экономит строки и 🌐 понятно.5. Менеджер контекста with 📂
❌ Старый способ:
file = open('data.txt', 'r')
try:
data = file.read()
finally:
file.close()✅ Как надо:
with open('data.txt', 'r') as file:
data = file.read()🎤 *Коммент*:
with сам закроет файл, как завершил. 👋 Экономия времени.6. Методы словаря get() и setdefault() 🔑
❌ Долго:
if key in my_dict:
value = my_dict[key]
else:
value = default_value
✅ Быстрее:
value = my_dict.get(key, default_value)
🎤 *Коммент*: Одной строкой получаем значение. 🤏 Легче понять и экономим символы.
7. Обмен значениями через множественное присваивание 🤝
❌ Лишние шаги:
temp = a
a = b
b = temp
✅ Как профи:
a, b = b, a
🎤 *Коммент*: Обмениваем значения без временных переменных, как в обменнике.
8. any() и all() — проверка сразу всех 🕵️♂️
❌ Не оптимально:
def has_negative(nums):
for num in nums:
if num < 0:
return True
return False
✅ Лучше так:
def has_negative(nums):
return any(num < 0 for num in nums)
🎤 *Коммент*:
any() проверяет сразу всё. Экономия строк и 💪 эффективность.9. f-строки 🎫
❌ Устарело:
name = 'Alice'
age = 30
message = 'Name: %s, Age: %d' % (name, age)
✅ Современный подход:
name = 'Alice'
age = 30
message = f'Name: {name}, Age: {age}'
🎤 *Коммент*: f-строки дают возможность вставлять значения прямо в текст. 💬 Быстрее и читаемо.
10. PEP 8 🧑🏫
❌ Как не надо:
def calculateSum(a,b):
return(a+b)
✅ Правильно:
def calculate_sum(a, b):
return a + b
🎤 *Коммент*: PEP 8 — это стиль, 👔 порядок и уважение. Если хочешь кодить как профи, придерживайся норм.
Доп. Практики 🛠
- Избегаем изменяемых объектов по умолчанию:
❌ Потенциальная проблема:
def append_to_list(value, my_list=[]):
my_list.append(value)
return my_list
✅ Надёжно:
def append_to_list(value, my_list=None):
if my_list is None:
my_list = []
my_list.append(value)
return my_list
🎤 *Коммент*: Изменяемые значения как дефолты могут привести к багам. 🛑 Лучше использовать
None.- Обработка ошибок через исключения:
❌ Не оптимально:
def divide(a, b):
if b == 0:
return None
else:
return a / b
✅ Используем try-except:
def divide(a, b):
try:
return a / b
except ZeroDivisionError:
print("Деление на ноль!")
🎤 *Коммент*: Исключения — это 👌 чистый способ ловить ошибки.
⚡️ *Вот такие дела, ребята! Применяйте эти фишки и пишите не просто рабочий код, а настоящий Python с душой!*
👍7💩3❤2🤡2👎1
Эй, народ, послушайте сюда! Сейчас я вам расскажу про такую фишку, как
Что за `memoryview` и зачем он нужен?
Представьте, вы пишете какой-нибудь супербыстрый сетевой сервис или игру, где важна каждая миллисекунда. Вам нужно работать с данными напрямую, без лишних копирований и задержек. Обычные методы не катят — они медленные и жрут память как не в себя.
Реальный пример: Быстрая обработка сетевых данных
Допустим, вы пилите свой сервер для онлайн-игры или чата. Данные летят пачками, и вам нужно их обрабатывать на лету. Если каждый раз копировать данные, ваш сервер начнёт тупить и лагать. А это никому не нужно, верно?
Вот как `memoryview` спасает ситуацию:
Вы получаете данные из сокета и создаёте
Почему это круто?
- Скорость: Нет лишних копирований данных. Вы работаете напрямую с буфером.
- Экономия памяти: При больших объёмах данных это критично.
- Гибкость: Можно легко работать с различными протоколами и форматами данных.
Ещё один пример: Изменение частей данных в массиве
Допустим, вы работаете с изображением или звуком, и вам нужно быстро менять части данных. С
Где без `memoryview` никуда?
- Работа с бинарными протоколами: Сетевые приложения, где нужно быстро парсить и формировать пакеты данных.
- Графика и мультимедиа: Обработка изображений, видео или аудио в реальном времени.
- Интеграция с низкоуровневыми библиотеками: Когда нужно передавать данные в C-расширения или использовать буферные интерфейсы.
Например, интеграция с NumPy
Если вы работаете с массивами NumPy и хотите передать данные в библиотеку, которая использует буферный интерфейс,
Заключение
memoryview, и почему без него иногда ну вообще никуда.Что за `memoryview` и зачем он нужен?
Представьте, вы пишете какой-нибудь супербыстрый сетевой сервис или игру, где важна каждая миллисекунда. Вам нужно работать с данными напрямую, без лишних копирований и задержек. Обычные методы не катят — они медленные и жрут память как не в себя.
memoryview — это как прямой доступ к памяти. Он позволяет смотреть на данные без копирования, работать с ними быстро и эффективно. Это как если бы вы получили мастер-ключ от всех данных и могли бы делать с ними всё, что душе угодно.Реальный пример: Быстрая обработка сетевых данных
Допустим, вы пилите свой сервер для онлайн-игры или чата. Данные летят пачками, и вам нужно их обрабатывать на лету. Если каждый раз копировать данные, ваш сервер начнёт тупить и лагать. А это никому не нужно, верно?
Вот как `memoryview` спасает ситуацию:
Вы получаете данные из сокета и создаёте
memoryview. Теперь вы можете быстро парсить протоколы, читать заголовки, проверять данные — и всё это без копирования и лишней траты памяти.import socket
# Создаём сокет и принимаем данные
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('example.com', 80))
sock.sendall(b'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n')
data = sock.recv(4096)
mv = memoryview(data)
# Предположим, первые 4 байта — это длина следующего сообщения
msg_length = int.from_bytes(mv[:4], 'big')
# Достаём само сообщение
message = mv[4:4+msg_length]
# Обрабатываем сообщение без копирования
process_message(message)
Почему это круто?
- Скорость: Нет лишних копирований данных. Вы работаете напрямую с буфером.
- Экономия памяти: При больших объёмах данных это критично.
- Гибкость: Можно легко работать с различными протоколами и форматами данных.
Ещё один пример: Изменение частей данных в массиве
Допустим, вы работаете с изображением или звуком, и вам нужно быстро менять части данных. С
memoryview это делается на раз-два.# Имеем изменяемый массив байтов, например, изображение
buffer = bytearray(b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09')
# Создаём memoryview
mv = memoryview(buffer)
# Меняем часть данных напрямую
mv[2:5] = b'\xFF\xFF\xFF'
print(buffer) # Выведет: bytearray(b'\x00\x01\xff\xff\xff\x05\x06\x07\x08\x09')
Где без `memoryview` никуда?
- Работа с бинарными протоколами: Сетевые приложения, где нужно быстро парсить и формировать пакеты данных.
- Графика и мультимедиа: Обработка изображений, видео или аудио в реальном времени.
- Интеграция с низкоуровневыми библиотеками: Когда нужно передавать данные в C-расширения или использовать буферные интерфейсы.
Например, интеграция с NumPy
Если вы работаете с массивами NumPy и хотите передать данные в библиотеку, которая использует буферный интерфейс,
memoryview позволяет сделать это без копирования.import numpy as np
# Создаём массив NumPy
arr = np.arange(10, dtype='int32')
# Создаём memoryview
mv = memoryview(arr)
# Передаём mv в функцию, ожидающую буферный интерфейс
some_function_that_uses_buffer(mv)
Заключение
memoryview — это мощный инструмент для тех, кто хочет выжать максимум из Python. Он позволяет работать с данными на низком уровне, экономить память и ускорять выполнение кода. Так что, если вы стремитесь к топовой производительности и хотите, чтобы ваш код был быстрым, как пуля, берите на вооружение memoryview и творите чудеса!👍7🔥3💩3🫡2👎1
🔥 UV: Менеджер пакетов для Python для настоящих пацанов 🔥
Йо, братва! Если вы до сих пор юзаете старые инструменты типа pip и pipenv, пора перейти на новый движ — UV. Это не просто менеджер пакетов, а целый универальный инструмент, который всё решает: ставит зависимости, создает виртуалки, даже нужную версию Python подкачивает. Всё это на Rust, так что скорость — как ракета 🚀.
---
💥 Чё такое UV?
Представьте, что у вас один инструмент, который заменяет сразу кучу утилит:
• _pip_
• _pip-tools_
• _virtualenv_
• _pyenv_
• _pipx_
и даже Git-фишки!
С UV вам не надо мутиться с кучей команд — одна команда, и все работает, как часы ⏱️.
---
⚡️ Основные фишки UV:
- Скорость — молния ⚡️
Благодаря Rust, установка пакетов и разрешение зависимостей происходит в 10–100 раз быстрее, чем у старых добрых инструментов. Кэш включен — и скорость супер!
- Все в одном 🎯
UV ставит зависимости, создает виртуалки и даже управляет версиями Python. Забудьте про разрозненные утилиты!
- Простота использования 🤙
Команды похожи на привычные:
Для виртуалок и Python:
- Git-интеграция 🔥
Хочешь брать зависимости прямо из Git-реп? UV тащит их, кэширует и обновляет без заморочек. Если нужны самые свежие фичи, — это твой выбор!
---
🛠 Как юзать UV на практике:
*Инициализация проекта*
Структура проекта готова, появляется
*Добавление зависимостей*
Зависимости пишутся в конфиг, lockfile генерится — у вас всегда один и тот же билд на всех машинах.
*Создание виртуального окружения*
Нужную версию Python ставит UV и создает виртуалку без лишних заморочек.
*Запуск утилит и скриптов*
Для утилит, типа Ruff:
А если есть скрипт с инлайн-зависимостями, добавляешь так:
Запускается скрипт в изолированном окружении — все как надо.
---
🚀 Git-движуха в UV
Слушай, UV не только пакеты ставит — он умеет тащить зависимости прямо из Git! Если тебе нужна свежая версия библиотеки из репы, указывай её, а UV все схватит, закэширует и подтянет обновления. Это реально спасает, когда работаешь с экспериментальными фичами или хочешь всегда быть на гребне волны 🌊.
---
🤘 Итог
UV — это настоящий хайп в мире Python. Он объединяет все, что нужно для быстрой и удобной разработки, и уже стал стандартом для настоящих пацанов, которые ценят свое время и не любят морочиться с настройками. Если хочешь работать быстро, четко и без лишних заморочек — переходи на UV, бро. Это будущее Python, и оно уже наступило!
Если есть вопросы или нужна помощь — пиши, всегда на связи! ✌️😎
Йо, братва! Если вы до сих пор юзаете старые инструменты типа pip и pipenv, пора перейти на новый движ — UV. Это не просто менеджер пакетов, а целый универальный инструмент, который всё решает: ставит зависимости, создает виртуалки, даже нужную версию Python подкачивает. Всё это на Rust, так что скорость — как ракета 🚀.
---
💥 Чё такое UV?
Представьте, что у вас один инструмент, который заменяет сразу кучу утилит:
• _pip_
• _pip-tools_
• _virtualenv_
• _pyenv_
• _pipx_
и даже Git-фишки!
С UV вам не надо мутиться с кучей команд — одна команда, и все работает, как часы ⏱️.
---
⚡️ Основные фишки UV:
- Скорость — молния ⚡️
Благодаря Rust, установка пакетов и разрешение зависимостей происходит в 10–100 раз быстрее, чем у старых добрых инструментов. Кэш включен — и скорость супер!
- Все в одном 🎯
UV ставит зависимости, создает виртуалки и даже управляет версиями Python. Забудьте про разрозненные утилиты!
- Простота использования 🤙
Команды похожи на привычные:
uv pip install flask
uv pip compile -o requirements.txt
uv pip sync requirements.txt
Для виртуалок и Python:
uv venv --python 3.11.9
uv python install 3.12
- Git-интеграция 🔥
Хочешь брать зависимости прямо из Git-реп? UV тащит их, кэширует и обновляет без заморочек. Если нужны самые свежие фичи, — это твой выбор!
---
🛠 Как юзать UV на практике:
*Инициализация проекта*
uv init my_project
cd my_project
Структура проекта готова, появляется
pyproject.toml и .python-version. Всё по понятиям!*Добавление зависимостей*
uv add "fastapi>=0.70"
Зависимости пишутся в конфиг, lockfile генерится — у вас всегда один и тот же билд на всех машинах.
*Создание виртуального окружения*
uv python install 3.11.9
uv venv --python 3.11.9
Нужную версию Python ставит UV и создает виртуалку без лишних заморочек.
*Запуск утилит и скриптов*
Для утилит, типа Ruff:
uvx ruff check .
А если есть скрипт с инлайн-зависимостями, добавляешь так:
uv add --script my_script.py "requests" "rich"
uv run my_script.py
Запускается скрипт в изолированном окружении — все как надо.
---
🚀 Git-движуха в UV
Слушай, UV не только пакеты ставит — он умеет тащить зависимости прямо из Git! Если тебе нужна свежая версия библиотеки из репы, указывай её, а UV все схватит, закэширует и подтянет обновления. Это реально спасает, когда работаешь с экспериментальными фичами или хочешь всегда быть на гребне волны 🌊.
---
🤘 Итог
UV — это настоящий хайп в мире Python. Он объединяет все, что нужно для быстрой и удобной разработки, и уже стал стандартом для настоящих пацанов, которые ценят свое время и не любят морочиться с настройками. Если хочешь работать быстро, четко и без лишних заморочек — переходи на UV, бро. Это будущее Python, и оно уже наступило!
Если есть вопросы или нужна помощь — пиши, всегда на связи! ✌️😎
1🔥5👍4⚡1💩1
Forwarded from Находки в опенсорсе
PEP 750: t-строки в 3.14
В питон добавили еще один способ форматировать строки. Теперь – со специальным АПИ для внешних интеграций.
- PEP: https://peps.python.org/pep-0750
- Реализация: https://github.com/python/cpython/pull/132662
Основная причина: использовать
string.templatelib.Template
Новый префикс
Обратите внимание, что при создании
Давайте посмотрим на примере. Допустим, мы хотим формировать URL из наших данных:
И сам код логики форматирования, где мы будем вставлять значения разным способом. Если у нас шаблон
И вот результат:
Только теперь наш
У нас есть полный контроль за процессом форматирования. Вот в чем суть данного ПЕПа.
Фичи одной строкой
- Работает
- Есть привычные определители формата:
-
- Поддерживается режим raw строк:
Как устроено внутри?
Интересные места имплементации:
- Изменения лексера
- Изменения грамматики языка
- Новое CAPI
- Новые классы
- Новый байткод
Обсуждение: как вам еще один способ форматирования строк?
| Поддержать | YouTube | GitHub | Чат |
В питон добавили еще один способ форматировать строки. Теперь – со специальным АПИ для внешних интеграций.
- PEP: https://peps.python.org/pep-0750
- Реализация: https://github.com/python/cpython/pull/132662
Основная причина: использовать
f строки удобно, но нет никакого АПИ для перехвата момента "вставки" или интерполяции значений. Например, при форматировании html или sql – требуется специальным образом делать escape для значений. И раньше код вида f"<div>{template}</div>" представлял собой дыру в безопасности и потенциальное место для XSS.string.templatelib.Template
Новый префикс
t не будет создавать объект str, он будет создавать объект класса string.templatelib.Template:
>>> user = 'sobolevn'
>>> template = t"Hi, {user}"
>>> template
Template(strings=('Hi, ', ''), interpolations=(Interpolation('sobolevn', 'user', None, ''),))
>>> from string.templatelib import Template
>>> isinstance(template, Template)
True
Обратите внимание, что при создании
template – у нас не произошло форматирование сразу. Мы создали объект, у которого есть свойства strings и interpolations, из которых можно собрать финальную отформатированную строку.Давайте посмотрим на примере. Допустим, мы хотим формировать URL из наших данных:
>>> domain = 'example.com'
>>> query = 'python string formatting is too complex'
>>> template = t'https://{domain}?q={query}'
И сам код логики форматирования, где мы будем вставлять значения разным способом. Если у нас шаблон
query, то мы будем использовать quote_plus для его форматирования. Остальные значения – будем вставлять как есть:
>>> from string.templatelib import Template, Interpolation
>>> from urllib.parse import quote_plus
>>> def format_url(template: Template) -> str:
... parts = []
... for part in template:
... match part:
... case str() as s: # regular string
... parts.append(s)
... case Interpolation(value, expression='query'):
... parts.append(quote_plus(value))
... case Interpolation(value):
... parts.append(value)
... return ''.join(parts)
И вот результат:
>>> format_url(template)
'https://example.com?q=python+string+formatting+is+too+complex'
Только теперь наш
Template был отформатирован. Нами. Ручками.У нас есть полный контроль за процессом форматирования. Вот в чем суть данного ПЕПа.
Фичи одной строкой
- Работает
= как обычно в f строках: t'{user=}'- Есть привычные определители формата:
!r, !s, .2f, тд-
t строки можно конкатенировать: t'Hello' + t' , world!' и t'Hello, ' + 'world'- Поддерживается режим raw строк:
rt"Hi \n!"Как устроено внутри?
Интересные места имплементации:
- Изменения лексера
- Изменения грамматики языка
- Новое CAPI
_PyTemplate- Новые классы
Template и Interpolation написанные на C- Новый байткод
BUILD_INTERPOLATION и BUILD_TEMPLATE
>>> import dis
>>> user = 'sobolevn'
>>> dis.dis('t"Hi, {user}"')
0 RESUME 0
1 LOAD_CONST 2 (('Hi, ', ''))
LOAD_NAME 0 (user)
LOAD_CONST 1 ('user')
BUILD_INTERPOLATION 2
BUILD_TUPLE 1
BUILD_TEMPLATE
RETURN_VALUE
Обсуждение: как вам еще один способ форматирования строк?
| Поддержать | YouTube | GitHub | Чат |
Python Enhancement Proposals (PEPs)
PEP 750 – Template Strings | peps.python.org
This PEP introduces template strings for custom string processing.
👍7❤1