Pythoner
7.23K subscribers
859 photos
27 videos
4 files
653 links
Полезные материалы по Python, которые будут интересны опытному и начинающему разработчику.

Сотрудничество - @flattys
Цены - @serpent_media

Канал на бирже: https://telega.in/c/pythonercode
Download Telegram
✈️Функция .strip() в Python по умолчанию удаляет пробелы в начале и конце строки. Это может быть особенно полезно при работе с данными, которые могут содержать случайные пробелы, которые могут помешать анализу данных или программированию. Например, строка ' Привет, мир! ' станет 'Привет, мир!' после использования .strip().

s = '     Привет, мир!     '
print(s.strip()) # Выведет: 'Привет, мир!'


➡️.strip() с аргументами
В дополнение к удалению пробелов, .strip() также может быть использован для удаления определенных символов из строки, передав их в качестве аргумента. Например, если мы хотим удалить определенный символ, такой как '#', из строки, мы можем это сделать, вызвав .strip('#'). Это удалит все экземпляры '#' из начала и конца строки.

s = '###Привет, мир!###'
print(s.strip('#')) # Выведет: 'Привет, мир!'


➡️.lstrip() и .rstrip()
Python также предлагает две вариации функции .strip(), которые являются .lstrip() и .rstrip(). Эти функции работают так же, как .strip(), но .lstrip() удаляет символы только с левой стороны строки, а .rstrip() - только с правой стороны.

s = '###Привет, мир!###'
print(s.lstrip('#')) # Выведет: 'Привет, мир!###'
print(s.rstrip('#')) # Выведет: '###Привет, мир!'


🐍 Pythoner
Please open Telegram to view this post
VIEW IN TELEGRAM
👍952🔥2
✈️Модульные тесты (или unit-тесты) — это автоматические тесты, которые проверяют работу отдельных функций, методов или классов в изоляции от остальной программы.

➡️Цель модульного теста — убедиться, что маленький блок кода работает правильно при разных входных данных:
# Функция, которую будем тестировать
def add(a, b):
return a + b

Теперь напишем модульный тест с использованием стандартного модуля unittest:
import unittest

class TestAddFunction(unittest.TestCase):
def test_add_positive_numbers(self):
self.assertEqual(add(2, 3), 5)

def test_add_negative_numbers(self):
self.assertEqual(add(-1, -2), -3)

def test_add_zero(self):
self.assertEqual(add(0, 5), 5)

if __name__ == '__main__':
unittest.main()


➡️Зачем нужны модульные тесты:
- Находят ошибки в логике функции.
- Упрощают рефакторинг (можно смело менять код — тесты покажут, что сломалось).
- Помогают при разработке: можно быстро проверить, работает ли новый код.
- Улучшают структуру кода — приходится писать функции так, чтобы их легко тестировать.

🐍 Pythoner
Please open Telegram to view this post
VIEW IN TELEGRAM
9👍3🔥3
✈️Основное различие между этими двумя методами состоит в том, что __new__ обрабатывает создание объекта, а __init__ обрабатывает его инициализацию.

__new__ вызывается автоматически при вызове имени класса (при создании экземпляра), тогда как init вызывается каждый раз, когда экземпляр класса возвращается __new__, передавая возвращаемый экземпляр в __init__ в качестве параметра self, поэтому даже если вы сохранили экземпляр где-нибудь глобально/статически и возвращали его каждый раз из __new__, для него все-равно будет каждый раз вызываться __init__.

Пример:

class Singleton:
_instance = None

def __new__(cls):
if cls._instance is None:
print("Создание объекта")
cls._instance = super().__new__(cls)
return cls._instance

def __init__(self):
print("Инициализация объекта")

a = Singleton()
b = Singleton()

⬆️Вывод:
Создание объекта
Инициализация объекта
Инициализация объекта


__new__ сработал один раз — объект создан.
__init__ вызвался дважды — каждый раз при создании экземпляра.

🐍 Pythoner
Please open Telegram to view this post
VIEW IN TELEGRAM
9🔥3👾3
✈️Зависимость (dependency) — это внешний объект, который нужен какому-то компоненту для работы. Внедрение зависимостей (Dependency Injection) — это способ передать нужные зависимости извне, а не создавать их внутри.

➡️Простой пример:
class Engine:
def start(self):
print("Engine started")

class Car:
def __init__(self, engine: Engine):
self.engine = engine

def run(self):
self.engine.start()

⬆️Здесь Car не создает Engine внутри себя. Внедрение происходит через конструктор.
engine = Engine()
car = Car(engine) # <-- внедрили зависимость
car.run()


➡️Как реализовать вручную в Python?
В Python DI часто реализуется через:

1. Конструктор (constructor injection):
class Service:
def __init__(self, db_client):
self.db = db_client


2. Setter-инъекция (через метод):
class Service:
def set_db(self, db_client):
self.db = db_client


3. Передача через параметры функции:
def handler(service: Service):
return service.do_stuff()


➡️Зачем это нужно?
- Легко тестировать (можно подменить зависимости моками)
- Повышает гибкость (меняем реализацию зависимости)
- Разделяет ответственность (класс делает только то, что должен)

🐍 Pythoner
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍4🔥2
👌2🤨2😐1🤓1
Что выдаст код выше
Anonymous Quiz
11%
True True
39%
True False
36%
False False
9%
False True
1%
None
3%
Error
🔥6👏2🤔2💯1👀1
🤔Разбор

str.isupper() -> bool
Возвращает флаг, указывающий не то, содержит ли строка символы только верхнего регистра.

Аналогично с islower, только для нижнего регистра.

Метод upper() возращает копию строки, в которой все буквы сконвертированы к большому регистру (заглавные буквы). Все остальные символы остаются неизмененными.

Аналогично с lower(), только к нижнему регистру.

В итоге получаем False == False, THIS IS NOW! == this is now! —> True, False


🐍 Pythoner
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥3👾31
👀Включите логирование медленных запросов, задав параметр log_min_duration_statement в конфигурации. Это позволит записывать все запросы, выполняющиеся дольше указанного времени.

👀Используйте команды EXPLAIN или EXPLAIN ANALYZE для просмотра плана выполнения запроса и оценки, где возникают задержки.

👀Проверьте, правильно ли настроены индексы для ускорения работы запросов, и при необходимости оптимизируйте сам запрос.

👀Анализируйте статистику запросов с помощью расширения pg_stat_statements, которое собирает информацию о времени выполнения и частоте запросов.

🐍 Pythoner
Please open Telegram to view this post
VIEW IN TELEGRAM
👍73🔥3
✈️Менеджер контекста позволяет выделять и освобождать ресурсы строго по необходимости. В Python за это отвечает блок с оператором with.
[async] with <функция> as <переменная>:
# до и после гарантированно срабатывают события входа в блок with и выхода из него.


__exit__ срабатывает в момент выхода из блока, в том числе по причине возникновения исключения. В этом случае в метод будут переданы exc_class, exc_instance и traceback.

➡️Пример:
with open('file.txt') as f:
data = f.read()
process_data(data)

Файл гарантированно закроется.

➡️Реализация своего контекстного менеджера на основе класса:
class Printable:
def __enter__(self):
print('enter')

def __exit__(self, type, value, traceback):
print('exit')


➡️Реализация своего контекстного менеджера с использованием встроенной библиотеки contextlib:
from contextlib import contextmanager

@contextmanager
def printable():
print('enter')
try:
yield
finally:
print('exit')


💡Контекстные менеджеры также можно использовать для временной замены параметров, переменных окружения, управления транзакциями в БД и других задач, где важен контроль за ресурсами.

🐍 Pythoner
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍3🥰2🔥1🤔1
✈️Elasticsearch — это распределенная поисковая система на основе Lucene, которая предоставляет мощные инструменты для поиска и анализа данных. Elasticsearch поддерживает множество функций, включая полнотекстовый поиск, агрегацию данных, машинное обучение и многое другое. Elasticsearch-py — это официальный клиент для работы с Elasticsearch в Python, который позволяет легко интегрировать Elasticsearch в ваши проекты.

➡️Основные возможности Elasticsearch:
- Полнотекстовый поиск: Elasticsearch предоставляет мощные инструменты для полнотекстового поиска, что позволяет быстро находить данные в больших объемах текста.

- Агрегация данных: Elasticsearch позволяет агрегировать данные, что полезно для аналитики и создания дашбордов.

- Машинное обучение: Elasticsearch поддерживает машинное обучение, что позволяет автоматически обнаруживать аномалии и тенденции в данных.

- Распределенная архитектура: Elasticsearch является распределенной системой, что позволяет масштабировать поиск и анализ данных.

➡️Пример cоздания клиента и индекса:
from elasticsearch import Elasticsearch

# Создание клиента Elasticsearch
es = Elasticsearch()

# Создание индекса
index_name = 'my_index'
es.indices.create(index=index_name)


➡️Агрегация данных:
# Агрегация данных
res = es.search(index=index_name, body={
'aggs': {
'author_count': {
'terms': {'field': 'author.keyword'}
}
}
})
print(res['aggregations'])


🐍 Pythoner
Please open Telegram to view this post
VIEW IN TELEGRAM
👍832🔥1
✈️Это операция, которая при повторном выполнении даёт тот же результат и не изменяет состояние системы дополнительно.

➡️Повышение надёжности:
Если операция случайно выполнится несколько раз (например, из-за сбоя в сети), идемпотентность гарантирует, что это не повлияет на итоговое состояние.

➡️Предотвращение дубликатов:
Позволяет избежать непреднамеренного добавления данных или повторного применения изменений.

Работа с HTTP:
1. GET — идемпотентен
GET /users/1


2. PUT — идемпотентен
PUT /users/1
{
"name": "Alice"
}

🔫Повторный вызов не изменит состояние.

3. POST — не идемпотентен
POST /users
{
"name": "Alice"
}

🔫Каждый вызов создаст нового пользователя.

➡️Идемпотентность в БД
Идемпотентный:
DELETE FROM users WHERE id = 5;

🔫Повторное выполнение ничего не изменит, если пользователь уже удалён.

Не идемпотентный:
INSERT INTO users (name) VALUES ('Alice');

🔫Повтор — создаст дубликаты.

💡Заключение
Идемпотентность = безопасное повторное выполнение.

🐍 Pythoner
Please open Telegram to view this post
VIEW IN TELEGRAM
👍633🔥2
✈️Утечка памяти в Python — это ситуация, когда объекты, которые больше не нужны, продолжают занимать память, потому что на них всё ещё существуют ссылки. Это мешает сборщику мусора освободить ресурсы.

➡️Причины утечки памяти:
- Сильные ссылки в замыканиях или глобальных структурах.
- Циклические ссылки (например, два объекта ссылаются друг на друга).
- Использование списков/словарей как кэшей без ограничения размера.
- Неочищенные обработчики событий, соединения или файлы.

➡️Как избежать:
- Использовать weakref для слабых ссылок.
- Очищать ненужные переменные (del, clear()).
- Контролировать размер кэшей.
- Проверять утечки с помощью инструментов вроде objgraph, gc, tracemalloc.

🐍 Pythoner
Please open Telegram to view this post
VIEW IN TELEGRAM
👍942🔥2
✈️Поверхностное и глубокое копирование объектов в Python различается по тому, как они обрабатывают вложенные объекты:
- Поверхностное копирование создает новый объект и сохраняет ссылки на вложенные объекты. Подходит для копирования объектов с иммутабельными вложенными элементами.

- Глубокое копирование создает полностью независимую копию объекта с вложенными элементами. Полезно при необходимости полностью отделить копию от оригинала.

import copy

original = [1, [2, 3], 4]
shallow_copied = copy.copy(original)
deep_copied = copy.deepcopy(original)

original[1][0] = 'изменено'
print(original) # [1, ['изменено', 3], 4]
print(shallow_copied) # [1, ['изменено', 3], 4] — вложенный список изменился
print(deep_copied) # [1, [2, 3], 4] — сохранено исходное состояние

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

🐍 Pythoner
Please open Telegram to view this post
VIEW IN TELEGRAM
8👍32🔥1
Forwarded from IT memer
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🤣5😁4
✈️Ты наверняка знаешь try/except, но как часто используешь finally?
А ведь он нужен там, где что бы ни случилось — надо прибраться:


➡️Когда без него никак:
1. Закрытие файлов / соединений:
f = open("data.txt")
try:
process(f)
finally:
f.close() # всегда выполнится


2. Откат транзакций:
try:
db.begin()
db.do_stuff()
finally:
db.rollback_or_commit()


3. Остановка фоновых задач:
try:
start_worker()
finally:
stop_worker()


💡Даже если в try будет return, break, ошибка или KeyboardInterrupt — finally всё равно отработает.
Это твоя гарантированная уборка.

🐍 Pythoner
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥114👍42
✈️При проверке паролей важно обеспечить безопасность ваших данных. Вместо сравнения паролей напрямую с помощью ==, лучше использовать библиотеку secrets. Это поможет защитить ваше приложение от атак.

➡️Пример кода:
import secrets

# Хранение паролей
password_storage = {}

# Функция для создания и хранения хэша пароля
def store_password(username, password):
    # Генерация случайного токена
    token = secrets.token_hex(16)
    password_storage[username] = {'token': token, 'password': password}

# Проверка пароля
def verify_password(username, provided_password):
    if username in password_storage:
        stored_password = password_storage[username]['password']
        # Сравнение паролей с использованием secrets.compare_digest
        return secrets.compare_digest(stored_password, provided_password)
    return False

# Использование
store_password("user1", "my_secure_password")

# Проверка входящего пароля
if verify_password("user1", "my_secure_password"):
    print("Пароль верный!")
else:
    print("Неверный пароль.")


💡Объяснение:
- Библиотека secrets используется для генерации криптографически стойкого токена, который можно хранить, но в этом примере основной акцент сделан на безопасном сравнении паролей.

- Функция compare_digest сравнивает пароли безопасным способом, защищая от тайминговых атак.

🐍 Pythoner
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍72🔥2
Во многих языках (C, Java, JavaScript) блоки кода обозначаются {}. В Python же используются отступы. Почему так?

- Читаемость — код без лишних {} и end выглядит чище.
- Принудительная структурность — нельзя "забыть закрыть скобку".
- Исторический фактор — Гвидо ван Россум вдохновлялся языком ABC.

➡️Пример кода на Python:
for i in range(3):
print(i) # Отступ обязателен


➡️Тот же код на C:
for (int i = 0; i < 3; i++) {
printf("%d\n", i);
}


🐍 Pythoner
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥94👍4
👍6🔥3
Что выдаст код выше
Anonymous Quiz
27%
"P"
7%
"t"
41%
"y"
25%
Error
🤔6🤷‍♀52🤨1
🤔Разбор

sorted("Python") → ['P', 'h', 'n', 'o', 't', 'y'].
[::-1] переворачивает список → ['y', 't', 'o', 'n', 'h', 'P'].
[0] возвращает первый элемент → "y".


🐍 Pythoner
Please open Telegram to view this post
VIEW IN TELEGRAM
11🔥7👀2👍1
✈️В FastAPI есть мощный инструмент для управления ресурсами приложения – @ asynccontextmanager в связке с lifespan. Это позволяет выполнить код инициализации при запуске и очистки при завершении приложения.

➡️Зачем это нужно?
- Подготовка базы данных: Создание таблиц, миграции.
- Инициализация соединений: Подключение к Redis, Kafka.
- Очистка ресурсов: Закрытие соединений, удаление временных файлов.

➡️Как это работает?
Декоратор @ asynccontextmanager создает асинхронный контекстный менеджер. Функция lifespan определяет, какой код выполняется до и после запуска приложения.

➡️Пример:


from contextlib import asynccontextmanager
from fastapi import FastAPI

# (Предположим, у вас есть функции create_db и close_db)
async def create_db():
    print("Подключаемся к базе данных...")
    # Здесь будет код подключения к БД
    await asyncio.sleep(1) # Имитация асинхронной операции
    print("База данных подключена!")

async def close_db():
    print("Закрываем соединение с базой данных...")
    # Здесь будет код закрытия соединения с БД
    await asyncio.sleep(1) # Имитация асинхронной операции
    print("Соединение с базой данных закрыто!")

@asynccontextmanager
async def lifespan(app: FastAPI):
    print("Запуск приложения...")
    await create_db()
    yield
    print("Завершение приложения...")
    await close_db()

app = FastAPI(lifespan=lifespan)

@app.get("/")
async def root():
    return {"message": "Hello World"}

# Запуск: uvicorn main:app --reload


- При запуске FastAPI (uvicorn main:app --reload) выполнится код до yield (создание таблиц).
- При остановке FastAPI выполнится код после yield (удаление таблиц).

lifespan + @ asynccontextmanager - это чистый и эффективный способ управлять ресурсами вашего FastAPI приложения!

🐍 Pythoner
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍32🔥1