Реальный Python
3.78K subscribers
801 photos
10 videos
7 files
848 links
Все о пайтон, новости, подборки на русском и английском. По всем вопросам @evgenycarter
Download Telegram
🧠 Как копировать объекты в Python правильно?

📌 Статья объясняет разницу между поверхностным и глубоким копированием объектов в Python.

🔍 Основные моменты:
= не копирует объект, а лишь создаёт новую ссылку на него.
• Поверхностное копирование (copy.copy()) создаёт новый объект, но вложенные объекты остаются общими.
• Глубокое копирование (copy.deepcopy()) рекурсивно копирует все вложенные объекты, обеспечивая полную независимость.
• Для пользовательских классов можно определить методы _copy_() и _deepcopy_() для контроля процесса копирования.

https://realpython.com/python-copy/

#python

👉 @python_real
🔹 Что такое пространства имён в Python?

В Python пространство имён — это система, которая обеспечивает уникальные имена для всех объектов, таких как переменные и функции. Простыми словами, это своего рода словарь, в котором имена являются ключами, а объекты — значениями.

Существует несколько типов пространств имён:
- Локальные: существуют внутри функции.
- Глобальные: существуют на уровне модуля.
- Встроенные: предоставляются Python по умолчанию (например, len() и print()).

Python управляет этими пространствами имён с помощью LEGB-правила:
- Local — локальное пространство имён.
- Enclosing — пространство имён замыкающей функции.
- Global — глобальное пространство имён.
- Built-in — встроенное пространство имён.

Когда интерпретатор встречает имя, он ищет его именно в таком порядке.

Понимание пространств имён помогает избежать неожиданных ошибок и писать более чистый код!


https://realpython.com/python-namespace/

#python

👉 @python_real
Генератор изображений кода на Python: делитесь кодом со стилем

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

Вы узнаете:

* Как использовать библиотеку Pillow для создания изображений;
* Как применять Pygments для подсветки синтаксиса;
* Как объединить эти инструменты в удобный CLI-интерфейс.

Что такое Pygments?

Pygments — это популярный инструмент для подсветки синтаксиса. Он поддерживает множество языков программирования и умеет преобразовывать код в HTML, LaTeX, RTF и другие форматы.

Пример:


from pygments import highlight
from pygments.lexers import PythonLexer
from pygments.formatters import ImageFormatter

code = 'print("Hello, world!")'
with open("code.png", "wb") as f:
f.write(highlight(code, PythonLexer(), ImageFormatter()))


Это создаст PNG-файл с изображением кода.

Настройка внешнего вида

С помощью параметров ImageFormatter можно настраивать:

* Шрифт (font_name);
* Размер шрифта (font_size);
* Цветовую схему (style);
* Включение/отключение номеров строк.

Пример настройки:


formatter = ImageFormatter(
font_name="DejaVu Sans Mono",
font_size=14,
line_numbers=True,
style="monokai"
)


Обработка входных данных

Для чтения кода из файла или stdin можно использовать модуль argparse:


import argparse
parser = argparse.ArgumentParser()
parser.add_argument("source", nargs="?", type=argparse.FileType("r"), default=sys.stdin)
args = parser.parse_args()
code = args.source.read()


Создание CLI-инструмента

Объединяя всё вместе, можно сделать простой CLI-скрипт, который принимает файл с кодом и генерирует изображение. В статье представлен полный пример кода.

Также рассматриваются вопросы производительности и расширения функциональности, например:

* Автоматическое определение языка;
* Поддержка разных форматов (JPEG, PNG);
* Сохранение и публикация изображений.

https://realpython.com/python-code-image-generator/

#python

👉 @python_real
Улучшаем логирование в Python с Loguru

Встроенный модуль logging в Python мощный, но довольно многословный и требует много шаблонного кода. Библиотека Loguru упрощает логирование, предлагая удобный и мощный API. Основные особенности и как начать использовать Loguru.

🔹Установка


pip install loguru


🔹Простой пример


from loguru import logger

logger.debug("Отладочное сообщение")
logger.info("Информационное сообщение")
logger.success("Сообщение об успешной операции")
logger.warning("Предупреждение")
logger.error("Ошибка")
logger.critical("Критическая ошибка")


Loguru автоматически добавляет:

* временную метку,
* уровень лога,
* путь к файлу и номер строки,
* и форматирует вывод по умолчанию.

🔹Удаление стандартного логгера

По умолчанию Loguru добавляет логгер в sys.stderr. Можно удалить его и добавить свой:


logger.remove()
logger.add("file.log", rotation="1 MB", compression="zip")


Здесь:

* rotation — лог будет разбит на части при достижении 1 МБ,
* compression — старые логи будут архивироваться в zip.

🔹Форматирование логов

Loguru позволяет настраивать формат:


logger.add("log.txt", format="{time} {level} {message}", level="INFO")


Можно использовать кастомные форматеры и сериализацию в JSON.

🔹Перехват исключений

Loguru умеет автоматически логировать исключения:


@logger.catch
def divide(a, b):
return a / b

divide(1, 0)


Это логирует traceback без необходимости писать try/except.

🔹Интеграция со стандартным логированием

Можно перенаправить стандартный logging в Loguru:


import logging
from loguru import logger

class InterceptHandler(logging.Handler):
def emit(self, record):
logger_opt = logger.opt(depth=6, exception=record.exc_info)
logger_opt.log(record.levelname, record.getMessage())

logging.basicConfig(handlers=[InterceptHandler()], level=0)


🔹Заключение

Loguru — это мощная альтернатива стандартному модулю logging, которая избавляет от шаблонного кода и делает логирование более выразительным и удобным. Особенно полезна для проектов, где читаемость и простота важны так же, как функциональность.


https://realpython.com/python-loguru/

#python

👉 @python_real
Please open Telegram to view this post
VIEW IN TELEGRAM
📊 Группировка данных в Polars с помощью `groupby`

Polars — это высокопроизводительная библиотека для анализа данных на Python. Она особенно хороша при работе с большими объемами данных, благодаря своей колонко-ориентированной архитектуре и использованию Rust под капотом.

Одним из ключевых инструментов для агрегации и анализа данных является метод .groupby().

Основы .groupby()

Пример базовой группировки:


import polars as pl

df = pl.DataFrame({
"city": ["London", "London", "Oslo", "Oslo", "Berlin", "Berlin"],
"year": [2020, 2021, 2020, 2021, 2020, 2021],
"value": [100, 150, 200, 220, 50, 80],
})

result = df.groupby("city").agg([
pl.col("value").mean().alias("average_value")
])
print(result)


Группировка по нескольким колонкам

Можно сгруппировать по нескольким признакам:


df.groupby(["city", "year"]).agg([
pl.col("value").sum().alias("total_value")
])


Использование выражений

Polars поддерживает ленивое выполнение (lazy evaluation) и мощную систему выражений:


df.groupby("city").agg([
(pl.col("value") * 2).mean().alias("double_avg")
])


Методы .groupby() в ленивом API

Для работы с большими данными предпочтительно использовать ленивый режим:


df_lazy = df.lazy()
result = df_lazy.groupby("city").agg([
pl.col("value").sum().alias("total")
])


Для запуска вычислений используется .collect():


result.collect()


Применение .groupby_dynamic() и .groupby_rolling()

Эти методы полезны при работе с временными рядами:

* groupby_dynamic: для агрегирования по фиксированным временным интервалам (например, по дням, неделям).
* groupby_rolling: для скользящего окна (например, скользящее среднее за 7 дней).

Пример:


df = pl.DataFrame({
"timestamp": pl.date_range(low=datetime(2022,1,1), high=datetime(2022,1,10), interval="1d"),
"value": range(10)
})

df.groupby_rolling(index_column="timestamp", period="3d").agg([
pl.col("value").mean().alias("rolling_avg")
])


https://realpython.com/polars-groupby/

#python

👉 @python_real
Вложенные циклы в Python

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

Начало работы с вложенными циклами

В Python есть два основных типа циклов — for и while.

* for -цикл проходит по элементам последовательности (списка, диапазона и т. д.), когда количество итераций известно заранее.
* while -цикл выполняется, пока истинно заданное условие, и полезен, когда число итераций заранее не определено.

Вложенный цикл создаётся размещением одного цикла внутри другого:


for outer_variable in outer_iterable:
for inner_variable in inner_iterable:
<body>


Для каждой итерации внешнего цикла внутренний выполняется полностью.

Аналогия: часовая и минутная стрелки часов. Часовая проходит круг за 12 часов, минутная — за 1 час, но работают они совместно.


for hour in range(24):
for minute in range(60):
print(f"{hour:02d}:{minute:02d}")


Практические примеры

Печать шаблонов


height = 6
sail_patterns = "*#-x+o"
for row in range(height):
pattern = ""
spacing = " " * (height - row)
for symbol in sail_patterns:
pattern += symbol * row + spacing
print(pattern)


Таблица умножения


for multiplicant in range(1, 11):
for multiplier in range(1, 4):
expression = f"{multiplicant:>2d} × {multiplier}"
product = multiplicant * multiplier
print(f"{expression} = {product:>2d}", end="\t")
print()


Суммирование элементов во вложенных списках


resource_donators = [
[8, 6, 3],
[9, 2, 7],
[4, 1, 5]
]
total_resources = 0
for planet in resource_donators:
for resource in planet:
total_resources += resource
print(total_resources) # 45


Парные комбинации без самих себя


players = ["Bonnie", "Mike", "Raj", "Adah"]
for player1 in players:
for player2 in players:
if player1 != player2:
print(f"{player1} vs {player2}")


Вложенный while


while True:
word = input("Введите слово (exit — для выхода): ")
if word == "exit":
break
for letter in word:
print(letter)


Частые проблемы вложенных циклов

* Область видимости переменных. Не используйте одинаковые имена во внешнем и внутреннем циклах.
* Читаемость. Глубокая вложенность усложняет понимание кода.
* Производительность. Каждый дополнительный уровень увеличивает временную сложность (часто до O(n²) и выше).

Оптимизация

* break и continue позволяют досрочно завершать цикл или пропускать ненужные итерации.
* List Comprehension делает выражения компактнее, хотя не всегда улучшает производительность.


# Поиск "bacon" с break
for layer in blt_sandwich:
for ingredient in layer:
if ingredient == target:
print("Found bacon!")
break
if target in layer:
break


Вывод

Вложенные циклы — мощный инструмент для работы с многомерными данными и повторяющимися задачами. Однако злоупотребление ими ухудшает читаемость и скорость. Используйте их осознанно, оптимизируйте при помощи break, continue и list comprehension, и никогда не забывайте о сложности алгоритма.

https://realpython.com/nested-loops-python/

#python

👉 @python_real
Как найти абсолютное значение в Python

В Python для чисел, массивов и собственных объектов используется встроенная функция abs(). В этом кратком руководстве вы узнаете:

* Как реализовать абсолютную функцию вручную.
* Как работает abs() с разными типами данных.
* Как расширить abs() для NumPy, pandas и своих классов.


1. Самостоятельная реализация


def absolute_value(x):
return x if x >= 0 else -x


Или через max:


def absolute_value(x):
return max(x, -x)


Через корень:


def absolute_value(x):
return (x**2) ** 0.5 # возвращает float


Но проще и эффективнее пользоваться abs().


2. Встроенная функция abs()

🔸Для целых и вещественных чисел сохраняет тип:


abs(-5) # 5
abs(-5.2) # 5.2

🔸Для комплексных чисел возвращает модуль:


z = 3 + 4j
abs(z) # 5.0

🔸Для Fraction и Decimal тоже работает «из коробки»:


from fractions import Fraction
abs(Fraction(-3, 4)) # Fraction(3, 4)

from decimal import Decimal
abs(Decimal("-0.75")) # Decimal('0.75')



3. Применение к коллекциям

Если у вас список чисел, используйте списковое включение или map:


temps = [1, -5, 3, -2]
[abs(x) for x in temps] # [1, 5, 3, 2]
list(map(abs, temps)) # [1, 5, 3, 2]



4. NumPy и pandas

🔸NumPy:


import numpy as np
arr = np.array([-1, -4, 0, 7])
abs(arr) # array([1, 4, 0, 7])

🔸pandas:


import pandas as pd
data = pd.Series([-2, 5, -3])
abs(data) # Series([2, 5, 3])



5. Собственные классы

Чтобы abs() работал для объектов вашего класса, определите метод .__abs__():


import math

class Vector:
def __init__(self, *coords):
self.coords = coords

def __abs__(self):
return math.hypot(*self.coords)

v = Vector(3, 4)
abs(v) # 5.0



Вывод:

🔸Для чисел abs() – оптимальный выбор.
🔸Для списков применяйте map или генератор списка.
🔸NumPy и pandas позволяют вызывать abs() прямо на массивах и DataFrame.
🔸Для собственных типов реализуйте .__abs__().

https://realpython.com/python-absolute-value/

#python

👉 @python_real
Определение собственной функции в Python

Функции — это фундаментальный строительный блок в Python. Они позволяют организовать код, переиспользовать его и сделать программу более читаемой. Создание собственной функции — это важный шаг на пути к более эффективной разработке.

Основы: def и имя функции

Функции в Python определяются с помощью ключевого слова def, за которым следует имя функции, круглые скобки (в которых можно указать параметры), и двоеточие:


def greet():
print("Привет!")


Теперь ты можешь вызвать функцию:


greet()


Аргументы и параметры

Ты можешь передавать данные в функцию через параметры:


def greet(name):
print(f"Привет, {name}!")


Вызов:


greet("Oleg")


Возврат значения

С помощью ключевого слова return можно вернуть результат из функции:


def add(a, b):
return a + b



result = add(3, 4)
print(result) # 7


Аргументы по умолчанию

Функции могут иметь параметры с значениями по умолчанию:


def greet(name="друг"):
print(f"Привет, {name}!")



greet() # Привет, друг!
greet("Oleg") # Привет, Oleg!


Именованные аргументы

Можно передавать аргументы явно по имени:


def describe_pet(animal, name):
print(f"У меня есть {animal}, его зовут {name}.")



describe_pet(animal="кот", name="Барсик")


Возвращение нескольких значений

Функции могут возвращать несколько значений с помощью кортежей:


def get_point():
return (3, 4)

x, y = get_point()



https://realpython.com/defining-your-own-python-function/

#python

👉 @python_real