Симуляция физики в Python: знакомство с Box2D
Привет! Меня зовут Иван, и сегодня я расскажу, как оживить ваши питоновские проекты с помощью реальной физики. Модуль Box2D — это порт знаменитого C++-движка, который используется даже в Angry Birds. Работая с Box2D, вы сможете симулировать столкновения, гравитацию, трение и многие другие законы Ньютона.
### Установка
Для начала установим обертку для Python:
### Первый шаг: «Мир» с гравитацией
Box2D моделирует «мир» (world), в котором живут все объекты. Добавим что-то простое: падение квадратика на землю.
### Шаг за шагом: симулируем падение
Box2D устроен так, что на каждом «шагающем» кадре пересчитывает все силы. Сделаем небольшой цикл:
Если вы запустите этот код, увидите, как координата вашего ящика падает: Box2D сам «роняет» объекты благодаря гравитации.
### Можно добавить столкновения
Box2D сразу учитывает коллизии: наш куб не провалится сквозь землю, остановится и немного подпрыгнет — настоящая физика!
### Как идти дальше?
Добавляйте больше динамических объектов: круги, многоугольники, соединяйте их шарнирами — с Box2D просто строить и домино, и симулятор машинки. Для визуализации можно использовать Pygame, pyglet или matplotlib, но для отработки логики совсем не обязательно что-то рисовать.
Box2D — отличный инструмент, чтобы почувствовать себя конструктором собственного физического мира, а главное, учиться наглядно — ведь питон в универе уже слишком скучен без весело прыгающих коробочек!
Привет! Меня зовут Иван, и сегодня я расскажу, как оживить ваши питоновские проекты с помощью реальной физики. Модуль Box2D — это порт знаменитого C++-движка, который используется даже в Angry Birds. Работая с Box2D, вы сможете симулировать столкновения, гравитацию, трение и многие другие законы Ньютона.
### Установка
Для начала установим обертку для Python:
pip install box2d-py
### Первый шаг: «Мир» с гравитацией
Box2D моделирует «мир» (world), в котором живут все объекты. Добавим что-то простое: падение квадратика на землю.
from Box2D import (b2World, b2PolygonShape, b2_staticBody, b2_dynamicBody)
world = b2World(gravity=(0, -10), doSleep=True)
# Создаём статический объект — землю
ground = world.CreateStaticBody(
position=(0, 0),
shapes=b2PolygonShape(box=(50, 1)),
)
# Динамический объект — наш падающий ящик
box = world.CreateDynamicBody(position=(0, 20))
box.CreatePolygonFixture(box=(1, 1), density=1, friction=0.3)
### Шаг за шагом: симулируем падение
Box2D устроен так, что на каждом «шагающем» кадре пересчитывает все силы. Сделаем небольшой цикл:
timeStep = 1.0 / 60
vel_iters, pos_iters = 6, 2
for i in range(60):
world.Step(timeStep, vel_iters, pos_iters)
print(f"Step {i}: Box y-position = {box.position.y:.2f}")
Если вы запустите этот код, увидите, как координата вашего ящика падает: Box2D сам «роняет» объекты благодаря гравитации.
### Можно добавить столкновения
Box2D сразу учитывает коллизии: наш куб не провалится сквозь землю, остановится и немного подпрыгнет — настоящая физика!
### Как идти дальше?
Добавляйте больше динамических объектов: круги, многоугольники, соединяйте их шарнирами — с Box2D просто строить и домино, и симулятор машинки. Для визуализации можно использовать Pygame, pyglet или matplotlib, но для отработки логики совсем не обязательно что-то рисовать.
Box2D — отличный инструмент, чтобы почувствовать себя конструктором собственного физического мира, а главное, учиться наглядно — ведь питон в универе уже слишком скучен без весело прыгающих коробочек!
Привет! Я — Иван, и сегодня у нас отличная тема: создание своих API на Python с помощью FastAPI. Если вы когда-нибудь хотели написать бэкенд для веб-приложения или просто быстро протестировать идею — вам определённо стоит познакомиться с этим модулем.
Зачем вообще нужен API?
API (Application Programming Interface) — это способ дать миру (или хотя бы вашему фронтенду/мобильному приложению) доступ к вашей программе. FastAPI — это современный и очень быстрый фреймворк, который позволяет создавать такие интерфейсы буквально за пару минут. Он поддерживает асинхронный код и автоматически документирует ваше API (Swagger/OpenAPI подключены "из коробки").
Минимальный пример
Запустив этот код (
Добавим обработку параметров
Хотите API с параметрами? Без проблем:
Теперь при обращении к
Работаем с запросами POST
Допустим, нужно принимать данные от пользователя. FastAPI умеет автоматически валидировать JSON с помощью Pydantic:
Воспользуйтесь страничкой /docs, чтобы отправить JSON — попробуйте передать
Почему FastAPI крут?
- Автоматические интерактивные docs.
- Поддержка асинхронности и скорости.
- Простота написания и расширения.
FastAPI уже стал любимцем у многих компаний и разработчиков, ведь он позволяет сосредоточиться на коде, а не на рутине. Попробуйте, и уверяю: у вас не возникнет желания возвращаться к более громоздким фреймворкам!
Зачем вообще нужен API?
API (Application Programming Interface) — это способ дать миру (или хотя бы вашему фронтенду/мобильному приложению) доступ к вашей программе. FastAPI — это современный и очень быстрый фреймворк, который позволяет создавать такие интерфейсы буквально за пару минут. Он поддерживает асинхронный код и автоматически документирует ваше API (Swagger/OpenAPI подключены "из коробки").
Минимальный пример
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "Hello, FastAPI!"}
Запустив этот код (
uvicorn main:app --reload
), вы моментально получите рабочее API: откройте браузер, зайдите на http://localhost:8000
, и увидите JSON-ответ. А если перейти на /docs
, там уже подробная документация и онлайн-тестирование всех маршрутов!Добавим обработку параметров
Хотите API с параметрами? Без проблем:
@app.get("/square/{number}")
def calculate_square(number: int):
return {"number": number, "squared": number * number}
Теперь при обращении к
/square/5
вы получите {"number": 5, "squared": 25}
.Работаем с запросами POST
Допустим, нужно принимать данные от пользователя. FastAPI умеет автоматически валидировать JSON с помощью Pydantic:
from pydantic import BaseModel
class Item(BaseModel):
name: str
price: float
@app.post("/items/")
def create_item(item: Item):
return {"item_name": item.name, "item_price": item.price}
Воспользуйтесь страничкой /docs, чтобы отправить JSON — попробуйте передать
{"name": "Keyboard", "price": 99.99}
.Почему FastAPI крут?
- Автоматические интерактивные docs.
- Поддержка асинхронности и скорости.
- Простота написания и расширения.
FastAPI уже стал любимцем у многих компаний и разработчиков, ведь он позволяет сосредоточиться на коде, а не на рутине. Попробуйте, и уверяю: у вас не возникнет желания возвращаться к более громоздким фреймворкам!
👍2
Привет! С вами Иван. Сегодня разберём одну из самых закулисных и магических тем Python — управление памятью: подсчёт ссылок и сборку мусора. Если вы когда-нибудь задумывались, почему Python не просит у вас явно освобождать память, то этот пост для вас!
## Подсчёт ссылок: сколько “рук” держат объект?
Python использует reference counting — счётчик ссылок на каждый объект. Когда переменная указывает на объект, счётчик увеличивается. Как только ни одна переменная на него больше не ссылается, объект считается “ненужным” и подлежит удалению.
Пример:
Магия проста: пока есть хотя бы одна “рука”, держащая объект, он живёт. Как только все переменные и ссылки исчезают — память освобождается.
## Сборка мусора: борьба с “каруселями”
Но что, если объекты ссылаются друг на друга? Простое удаление переменных не сработает — каждый будет держать “за руку” другого, и счётчики не опустятся до нуля! Тут появляется garbage collector.
В Python модуль
Garbage collector периодически сканирует объекты, чтобы найти непростые циклы, и удаляет их, когда доступ к ним невозможен.
## Практические советы
- Не бойтесь “загрязнить” память — Python делает всё сам.
- Если работаете с большим количеством данных и видите рост памяти — попробуйте вызвать
- Используйте weakref, если нужен временный “тонкий” доступ без увеличения счётчика ссылок.
Пусть ваша память всегда будет свободна для новых идей!
## Подсчёт ссылок: сколько “рук” держат объект?
Python использует reference counting — счётчик ссылок на каждый объект. Когда переменная указывает на объект, счётчик увеличивается. Как только ни одна переменная на него больше не ссылается, объект считается “ненужным” и подлежит удалению.
Пример:
import sys
a = []
print(sys.getrefcount(a)) # Обычно вернёт 2 (a и аргумент функции)
b = a
print(sys.getrefcount(a)) # Уже 3 ссылки (a, b, и аргумент)
del b
print(sys.getrefcount(a)) # Снова 2
Магия проста: пока есть хотя бы одна “рука”, держащая объект, он живёт. Как только все переменные и ссылки исчезают — память освобождается.
## Сборка мусора: борьба с “каруселями”
Но что, если объекты ссылаются друг на друга? Простое удаление переменных не сработает — каждый будет держать “за руку” другого, и счётчики не опустятся до нуля! Тут появляется garbage collector.
В Python модуль
gc
следит за такими “каруселями”:import gc
class Node:
def __init__(self):
self.ref = None
x = Node()
y = Node()
x.ref = y
y.ref = x
del x, y # Ссылок на объекты нет, но карусель всё ещё существует
gc.collect() # Явно собираем мусор, объекты будут удалены
Garbage collector периодически сканирует объекты, чтобы найти непростые циклы, и удаляет их, когда доступ к ним невозможен.
## Практические советы
- Не бойтесь “загрязнить” память — Python делает всё сам.
- Если работаете с большим количеством данных и видите рост памяти — попробуйте вызвать
gc.collect()
.- Используйте weakref, если нужен временный “тонкий” доступ без увеличения счётчика ссылок.
Пусть ваша память всегда будет свободна для новых идей!
👍2
Привет! На связи Иван, и сегодня в нашем блоге разберём магию перенаправления потоков ввода и вывода в Python. Зачем это нужно? Например, если вы хотите записывать вывод вашей программы не только на экран, но и в файл, или "обмануть" функцию, которая традиционно ждёт пользовательский ввод, подсовывая ей данные автоматически. Готовы? Погнали!
## Перенаправляем stdout: вывод в файл и обратно
Для работы с потоками в Python служит модуль
Теперь строка "Hello, file!" попадёт в файл, а "Hello, console!" — как обычно, в терминал.
## Подменяем stdin: автоматизируем ввод
Точно так же можно подменить поток ввода. Это удобно, когда нужно тестировать функции, требующие input от пользователя.
В этом примере input не ждёт ввода, а сразу получает '42'. Удобно для юнит-тестов!
## А если хочется перехватить вывод программы?
Трюк с подменой stdout особенно крут, когда хочется легко перехватывать и анализировать результат работы каких-то функций. Например, сделаем функцию, возвращающую всё, что она напечатала:
Теперь мы можем обработать результат как строку — не круто ли?
На этом всё! Не стесняйтесь экспериментировать с потоками: это ключ к автоматизации, тестированию и оптимизации ваших программ. Желаю отличной практики и новых открытий с Python!
Иван.
## Перенаправляем stdout: вывод в файл и обратно
Для работы с потоками в Python служит модуль
sys
. Самый популярный поток — это sys.stdout
, который по умолчанию пишет в консоль. Давайте заставим его писать в файл:import sys
with open('output.txt', 'w') as file:
original_stdout = sys.stdout # сохраняем ссылку на стандартный поток
sys.stdout = file # перенаправляем stdout в файл
print("Hello, file!")
sys.stdout = original_stdout # возвращаем stdout обратно
print("Hello, console!")
Теперь строка "Hello, file!" попадёт в файл, а "Hello, console!" — как обычно, в терминал.
## Подменяем stdin: автоматизируем ввод
Точно так же можно подменить поток ввода. Это удобно, когда нужно тестировать функции, требующие input от пользователя.
import sys
from io import StringIO
test_input = StringIO('42\n')
original_stdin = sys.stdin
sys.stdin = test_input
number = int(input("Enter a number: "))
print("Number x2:", number * 2)
sys.stdin = original_stdin
В этом примере input не ждёт ввода, а сразу получает '42'. Удобно для юнит-тестов!
## А если хочется перехватить вывод программы?
Трюк с подменой stdout особенно крут, когда хочется легко перехватывать и анализировать результат работы каких-то функций. Например, сделаем функцию, возвращающую всё, что она напечатала:
def capture_output(func):
import sys
from io import StringIO
output = StringIO()
original_stdout = sys.stdout
sys.stdout = output
try:
func()
finally:
sys.stdout = original_stdout
return output.getvalue()
def hello():
print("Hello from function!")
text = capture_output(hello)
print("Captured:", text)
Теперь мы можем обработать результат как строку — не круто ли?
На этом всё! Не стесняйтесь экспериментировать с потоками: это ключ к автоматизации, тестированию и оптимизации ваших программ. Желаю отличной практики и новых открытий с Python!
Иван.
❤2
Привет! С вами Иван, сегодня копнем чуточку глубже — поговорим о метаклассах в Python.
Многие слышали про метаклассы как о чем-то мистическом, но на деле — это просто классы, которые создают другие классы. Да-да, в Python даже классы — это объекты, и за тем, как они создаются, следит метакласс. В обычной жизни мы редко сталкиваемся с ними, но если нужно гибко и аккуратно управлять поведением всех классов в проекте — метаклассы становятся отличным инструментом.
## Для чего нужны метаклассы?
С их помощью можно:
- Автоматически модифицировать классы при создании (например, добавлять методы или атрибуты);
- Навязывать единый стиль (например, проверять именование или структуру классов);
- Реализовывать паттерны, вроде Singleton, прямо “на уровне класса”.
## Базовый пример
Создадим метакласс, который автоматически добавляет атрибут
## Валидация структуры класса
Иногда хочется убедиться, что каждый класс имеет нужные методы:
## Подмена методов на лету
Допустим, хотим, чтобы все методы начинали логировать своё вызовы:
Как видите, метаклассы — секретная дверца Python к по-настоящему мощным и гибким фичам. Пользуются ими редко, но знать о них точно стоит!
Многие слышали про метаклассы как о чем-то мистическом, но на деле — это просто классы, которые создают другие классы. Да-да, в Python даже классы — это объекты, и за тем, как они создаются, следит метакласс. В обычной жизни мы редко сталкиваемся с ними, но если нужно гибко и аккуратно управлять поведением всех классов в проекте — метаклассы становятся отличным инструментом.
## Для чего нужны метаклассы?
С их помощью можно:
- Автоматически модифицировать классы при создании (например, добавлять методы или атрибуты);
- Навязывать единый стиль (например, проверять именование или структуру классов);
- Реализовывать паттерны, вроде Singleton, прямо “на уровне класса”.
## Базовый пример
Создадим метакласс, который автоматически добавляет атрибут
category = 'custom_class'
во все классы:class BaseMeta(type):
def __new__(mcs, name, bases, attrs):
attrs['category'] = 'custom_class'
return super().__new__(mcs, name, bases, attrs)
class ExampleClass(metaclass=BaseMeta):
pass
print(ExampleClass.category) # custom_class
## Валидация структуры класса
Иногда хочется убедиться, что каждый класс имеет нужные методы:
class MethodCheckerMeta(type):
def __new__(mcs, name, bases, attrs):
if 'process' not in attrs:
raise TypeError('Class must define "process" method')
return super().__new__(mcs, name, bases, attrs)
class DataWorker(metaclass=MethodCheckerMeta):
def process(self):
print("Processing...")
# class BadWorker(metaclass=MethodCheckerMeta):
# pass # Ошибка при определении класса!
## Подмена методов на лету
Допустим, хотим, чтобы все методы начинали логировать своё вызовы:
def log_decorator(func):
def wrapper(*args, **kwargs):
print(f'Call {func.__name__}')
return func(*args, **kwargs)
return wrapper
class LoggerMeta(type):
def __new__(mcs, name, bases, attrs):
for key, val in attrs.items():
if callable(val):
attrs[key] = log_decorator(val)
return super().__new__(mcs, name, bases, attrs)
class UserAction(metaclass=LoggerMeta):
def update_profile(self):
print("Profile updated")
u = UserAction()
u.update_profile()
Как видите, метаклассы — секретная дверца Python к по-настоящему мощным и гибким фичам. Пользуются ими редко, но знать о них точно стоит!
👍2
Привет, друзья! На связи Иван, и сегодня мы окунемся в мир Python-модуля, который любит любой ценитель изящного кода — речь о
## Зачем вообще нужен itertools?
Когда возникает задача "перебрать все комбинации", "замиксовать значения" или "иcкать все варианты", большинство новичков берёт в руки вложенные циклы и — устаёт. Но если вы знаете про
Давайте разбираться с основами!
### 1. Комбинации
Выберите любые 2 книги из 4-х? За нас всё сделает
Этот код выведет все возможные пары книг — и ни одна не повторится.
### 2. Перестановки
Все возможные варианты порядка трёх футболистов на пьедестале? Простая задача для
Здесь будет 6 вариантов (3!) — идеально для задач, где важен порядок.
### 3. Произведения (Декартово произведение)
Когда нужно смиксовать элементы из разных коллекций, используем
Ты быстро получаешь комбинации вида: ('red', 'S'), ('red', 'M'), …
### 4. Комбинации с повторениями
Допустим, нужно узнать, какие мороженое можно собрать из 3-х шариков, если вкусы могут повторяться:
Получаем все возможные варианты с повторениями, без головной боли!
---
itertools
. Этот модуль открыт как сундук с сокровищами для разных комбинаторных задач: от банального перебора вариантов до создания хитроумных перестановок.## Зачем вообще нужен itertools?
Когда возникает задача "перебрать все комбинации", "замиксовать значения" или "иcкать все варианты", большинство новичков берёт в руки вложенные циклы и — устаёт. Но если вы знаете про
itertools
, эти задачи превращаются в пару строк элегантного кода.Давайте разбираться с основами!
### 1. Комбинации
Выберите любые 2 книги из 4-х? За нас всё сделает
itertools.combinations
:from itertools import combinations
books = ['The Hobbit', 'Python 101', 'Moby Dick', 'War and Peace']
for combo in combinations(books, 2):
print(combo)
Этот код выведет все возможные пары книг — и ни одна не повторится.
### 2. Перестановки
Все возможные варианты порядка трёх футболистов на пьедестале? Простая задача для
permutations
:from itertools import permutations
players = ['Alice', 'Bob', 'Charlie']
for p in permutations(players):
print(p)
Здесь будет 6 вариантов (3!) — идеально для задач, где важен порядок.
### 3. Произведения (Декартово произведение)
Когда нужно смиксовать элементы из разных коллекций, используем
product
:from itertools import product
colors = ['red', 'green']
sizes = ['S', 'M']
for item in product(colors, sizes):
print(item)
Ты быстро получаешь комбинации вида: ('red', 'S'), ('red', 'M'), …
### 4. Комбинации с повторениями
Допустим, нужно узнать, какие мороженое можно собрать из 3-х шариков, если вкусы могут повторяться:
from itertools import combinations_with_replacement
flavors = ['chocolate', 'vanilla', 'strawberry']
for combo in combinations_with_replacement(flavors, 3):
print(combo)
Получаем все возможные варианты с повторениями, без головной боли!
---
itertools
— это как швейцарский нож для работы с итерациями. Освоив всего несколько функций, ты вытесняешь громоздкие циклы лаконичными генераторами. Заходи в документацию и пробуй новые инструменты — и Python станет для тебя ещё более мощным и гибким!👍1
Привет, друзья! С вами Иван, и сегодня мы погрузимся в захватывающий мир многопоточности на Python с помощью модуля
### Что такое потоки и зачем они нужны?
Обычно Python выполняет код последовательно. Но что если вам нужно скачивать картинки, опрашивать API и тут же обновлять интерфейс? Здесь на сцену выходит
### Простой пример: запуск двух задач одновременно
Посмотрим, как это выглядит на практике:
Две функции работают параллельно: одна выводит числа, другая — буквы.
### Как управлять потоками?
- Создание: каждый поток — это экземпляр
- Запуск:
- Ожидание завершения:
### А если нужно знать, работает ли поток?
Метод
### Безопасность данных — используем Lock
Потоки могут обращаться к одним и тем же данным, поэтому важно использовать блокировки (
---
threading
. Даже если вы пока не запускали код "параллельно", этот пост для вас!### Что такое потоки и зачем они нужны?
Обычно Python выполняет код последовательно. Но что если вам нужно скачивать картинки, опрашивать API и тут же обновлять интерфейс? Здесь на сцену выходит
threading
— стандартный модуль для работы с потоками. Потоки (threads) позволяют запускать функции параллельно, не ожидая завершения одной, чтобы стартовать другую.### Простой пример: запуск двух задач одновременно
Посмотрим, как это выглядит на практике:
import threading
import time
def print_numbers():
for i in range(5):
print(f"Number: {i}")
time.sleep(1)
def print_letters():
for letter in 'abcde':
print(f"Letter: {letter}")
time.sleep(1)
t1 = threading.Thread(target=print_numbers)
t2 = threading.Thread(target=print_letters)
t1.start()
t2.start()
t1.join()
t2.join()
print("Done!")
Две функции работают параллельно: одна выводит числа, другая — буквы.
### Как управлять потоками?
- Создание: каждый поток — это экземпляр
threading.Thread
, который принимает функцию через параметр target
, и ее аргументы через args
.- Запуск:
.start()
начинает выполнение в новом потоке.- Ожидание завершения:
.join()
блокирует основной поток, пока дочерний не закончится.### А если нужно знать, работает ли поток?
worker = threading.Thread(target=time.sleep, args=(3,))
worker.start()
print(worker.is_alive()) # True
worker.join()
print(worker.is_alive()) # False
Метод
is_alive()
вернет True
, пока поток еще трудится.### Безопасность данных — используем Lock
Потоки могут обращаться к одним и тем же данным, поэтому важно использовать блокировки (
Lock
):counter = 0
lock = threading.Lock()
def increment():
global counter
for _ in range(1000):
with lock:
counter += 1
threads = [threading.Thread(target=increment) for _ in range(10)]
for t in threads: t.start()
for t in threads: t.join()
print(counter) # Всегда 10000!
Lock
гарантирует, что только один поток изменяет переменную в конкретный момент.---
threading
открывает путь к одновременному исполнению кода и ускоряет задачи ввода-вывода. Главное — не забывайте про безопасный доступ к общим данным, и тогда ваши приложения станут гораздо мощнее!👍1
## Schedule — твой персональный дирижёр в мире повторяющихся задач
Всем привет! С вами Иван, и сегодня мы поговорим о настоящей находке для каждого, кто устал вручную запускать одни и те же функции в Python. Представляю вам модуль
### Что это такое?
Модуль
### Установка
Перед стартом — минутка магии в консоли:
### Примеры использования
Разберём на пальцах. Допустим, вы хотите, чтобы скрипт отправлял напоминание выпить воды каждый час. Вот как это делается:
Теперь функция
А если нужно выполнять задачу только по рабочим дням — не проблема!
Можно и покреативить: запускать задачу каждые 10 минут или, скажем, в определённое время суток:
### Фишки модуля
-
- Время можно указывать сразу для нескольких задач с разной периодичностью.
- Работает просто: без лишних настроек, конфигов и заморочек.
### Минусы и ограничения
Модуль не умеет работать в фоне — если закроете скрипт, задачи выполняться не будут. Для продвинутых сценариев (например, для серверов) нужны другие решения, но для учебных и простых домашних проектов
Практикуйте и экспериментируйте, ведь расписание — ключ к продуктивности даже в программировании!
Всем привет! С вами Иван, и сегодня мы поговорим о настоящей находке для каждого, кто устал вручную запускать одни и те же функции в Python. Представляю вам модуль
schedule
— отличный инструмент для простого управления повторяющимися задачами.### Что это такое?
Модуль
schedule
позволяет легко и понятно запускать ваши Python-функции по расписанию: каждый день, каждый час, по выходным или хоть каждую пятую минуту. На вид — как мини-крон прямо внутри кода, только гораздо дружелюбнее.### Установка
Перед стартом — минутка магии в консоли:
pip install schedule
### Примеры использования
Разберём на пальцах. Допустим, вы хотите, чтобы скрипт отправлял напоминание выпить воды каждый час. Вот как это делается:
import schedule
import time
def remind_water():
print("Time to drink some water!")
schedule.every(1).hour.do(remind_water)
while True:
schedule.run_pending()
time.sleep(1)
Теперь функция
remind_water
будет срабатывать раз в час, пока скрипт работает.А если нужно выполнять задачу только по рабочим дням — не проблема!
def check_email():
print("Don't forget to check your email!")
schedule.every().monday.do(check_email)
schedule.every().tuesday.do(check_email)
schedule.every().wednesday.do(check_email)
schedule.every().thursday.do(check_email)
schedule.every().friday.do(check_email)
Можно и покреативить: запускать задачу каждые 10 минут или, скажем, в определённое время суток:
def backup_files():
print("Backup started!")
schedule.every(10).minutes.do(backup_files)
schedule.every().day.at("23:00").do(backup_files)
### Фишки модуля
-
schedule.run_pending()
проверяет — не пора ли что запустить, и делает это.- Время можно указывать сразу для нескольких задач с разной периодичностью.
- Работает просто: без лишних настроек, конфигов и заморочек.
### Минусы и ограничения
Модуль не умеет работать в фоне — если закроете скрипт, задачи выполняться не будут. Для продвинутых сценариев (например, для серверов) нужны другие решения, но для учебных и простых домашних проектов
schedule
— настоящее спасение.Практикуйте и экспериментируйте, ведь расписание — ключ к продуктивности даже в программировании!