Python для начинающих
1.06K subscribers
289 photos
3 videos
232 files
61 links
Python для начинающих
Download Telegram
Как измерять и оптимизировать использование памяти в Python-программах
Когда Python пишет в память: как измерять и оптимизировать использование памяти

Представьте, что у вас в рюкзаке лежат книги. Если у вас всего пара книжек — проблем нет. Но если вы случайно запихнули туда энциклопедию в 10 томах, да ещё на каждой странице – картинка, быть беде: рюкзак рвётся. Так же и с памятью в Python — можно писать лёгкий код, а можно незаметно нагрузить память до отказа. Сегодня поговорим о том, как следить за объёмом используемой памяти и как её оптимизировать.

📏 Измеряем: кто сколько ест?

Python по умолчанию не показывает, сколько памяти занял тот или иной объект. К счастью, у нас есть модуль sys и отличная библиотека pympler.

Начнём с простого:

import sys

data = [i for i in range(10000)]
print(sys.getsizeof(data)) # Размер самого списка
print(sys.getsizeof(data[0])) # Размер одного элемента


Но sys.getsizeof() возвращает только «голый» размер объекта, без вложенных данных. Например, список из 10 000 строк займёт гораздо больше, чем просто «список». Для глубокого анализа лучше использовать pympler.

from pympler import asizeof

data = [str(i) for i in range(10000)]
print(asizeof.asizeof(data))


Заметка: установите pympler через pip install pympler, если он ещё не установлен.

☝️ Проверь себя: строки и множества

Некоторые стандартные структуры данных в Python могут неожиданно потреблять много памяти. Например, множества set занимают больше памяти, чем списки, а строки — иногда ведут себя не так, как ожидаешь:

a = 'hello' * 1000
b = ['hello'] * 1000

print(sys.getsizeof(a), 'vs', sys.getsizeof(b))


📉 Оптимизируем: меньше, но лучше

- Используйте генераторы вместо списков там, где это возможно. Они не хранят все элементы в памяти одновременно:

sum_gen = sum(i for i in range(10**7))  # Генератор
sum_list = sum([i for i in range(10**7)]) # Список, занимает в разы больше памяти


- Замените большие словари с повторяющимися значениями на collections.defaultdict или array/struct, особенно в случае числовых данных.

- Не держите в памяти то, что уже не нужно. Иногда достаточно просто удалить переменные:

import gc

del large_data
gc.collect()


- Используйте __slots__ в ваших классах, если количество атрибутов фиксировано. Это сокращает накладные расходы на хранение объектов:

class Lightweight:
__slots__ = ['name', 'value']
def __init__(self, name, value):
self.name = name
self.value = value


🚀 Вывод

Python — не самый «худенький» язык, когда речь заходит о памяти. Но понимание того, как и где расходуются ресурсы, творит чудеса. Используя простые приёмы и правильные инструменты, даже «тяжёлый» код можно привести в форму. А значит — приложение работает быстрее, а сервер не падает при каждом запуске анализа данных.
👍2
Создание простых текстовых игр с помощью модуля curses
🕹️ Как создать простую текстовую игру с помощью модуля curses в Python

Привет! С вами Иван, и сегодня мы окунёмся в мир текстовых интерфейсов на чистом Python. Игры — отличный способ попрактиковаться в программировании. А текстовые игры — это минимум графики, максимум фантазии. Но даже текст можно приукрасить: анимацией, управлением клавишами и взаимодействием в реальном времени. Всё это даёт модуль curses.

Что такое curses?

Модуль curses — это оболочка для работы с терминалом. Он позволяет рисовать "на лету", обрабатывать нажатия клавиш без ENTER'а, управлять цветами и позициями текста, и всё это — удобно, не покидая консолей. Работает из коробки на Linux и macOS. На Windows потребуется установить windows-curses:
pip install windows-curses


Создаём простую игру: уклоняйся от падающих звёзд 🌠

Представьте: звёзды падают сверху вниз, а вы — смайлик 🙂, который бегает внизу и старается не попасть под удар.

Давайте напишем минимальную, но полностью работающую аркаду на curses:

import curses
import random
import time

def main(stdscr):
curses.curs_set(0)
stdscr.nodelay(True)
stdscr.timeout(100)

sh, sw = stdscr.getmaxyx()
player_x = sw // 2
player = "🙂"
stars = []
score = 0

while True:
stdscr.clear()

# Рисуем игрока
stdscr.addstr(sh - 1, player_x, player)

# Генерация новых звезд
if random.randint(1, 10) == 1:
star_x = random.randint(0, sw - 1)
stars.append([0, star_x])

# Обновляем позиции звезд
for star in stars:
star[0] += 1
if star[0] < sh:
stdscr.addstr(star[0], star[1], "*")

# Проверка на столкновение
for star in stars:
if star[0] == sh - 1 and star[1] == player_x:
msg = f"Game Over! Score: {score}"
stdscr.addstr(sh // 2, sw // 2 - len(msg) // 2, msg)
stdscr.refresh()
time.sleep(2)
return

# Удаляем вышедшие за границу звезды и увеличиваем счёт
stars = [star for star in stars if star[0] < sh]
score += 1

# Управление
key = stdscr.getch()
if key == curses.KEY_LEFT and player_x > 0:
player_x -= 1
elif key == curses.KEY_RIGHT and player_x < sw - 1:
player_x += 1
elif key == ord('q'):
break

stdscr.refresh()

curses.wrapper(main)


📦 Что мы здесь используем:

- nodelay(True) и timeout(100) — для плавного обновления экрана;
- curs_set(0) — отключение мигающего курсора;
- getch() — для чтения нажатий клавиш без ENTER'а;
- addstr(y, x, text) — вывод текста в нужную позицию;
- getmaxyx() — узнаем размеры терминала;

🔥 Игра проста, но в ней уже есть движение, случайность, управление и счёт. На этой базе можно развивать игру: добавить жизни, уровни или спецэффекты.

Если вы устали от обычных input/print — попробуйте curses. Он идеален для создания собственных мини-игр, TUI-интерфейсов, и просто для фана.

До встречи в следующем посте. Будем учиться строить терминальное меню и прокачаем наши игрушки! 👾
Использование namedtuple для более читаемого кода
Когда кортеж — хорошо, но читаемость важнее: знакомимся с namedtuple

Когда-то каждый из нас начинал с простых структур данных в Python: списков, словарей и кортежей. Но вот беда — кортежи хоть и компактны, но напрочь забывают об удобстве чтения. Спустя пару недель ты смотришь на что-то вроде tuple2 и пытаешься вспомнить, был ли это адрес, возраст или погрешность измерения.

А теперь представь — можно оставить легковесность, но добавить читаемость. Волшебство? Почти. Это namedtuple.

📦 Что такое namedtuple?

Это тот самый кортеж, только с возможностью обращаться к полям по имени. Импортируется он из стандартного модуля collections:

from collections import namedtuple


Выглядит как класс, работает как кортеж. Удобно, быстро и читаемо.

🚀 Создаем первый namedtuple

Допустим, мы пишем GPS-трекер. Точка на карте содержит имя координаты, широту и долготу. Можно сделать это так:

from collections import namedtuple

Location = namedtuple('Location', ['name', 'latitude', 'longitude'])

place = Location(name='Home', latitude=55.750446, longitude=37.617494)

print(place)
print(place.name) # 'Home'
print(place.latitude) # 55.750446


Уже лучше, чем tuple0, правда? А еще у такого объекта сохраняется понятная структура при выводе и его можно распаковывать как обычный кортеж:

name, lat, lon = place


Не только красиво, но и полезно

Из коробки namedtuple дает такие плюшки:

- Легковесность как у tuple (namedtuple неизменяем);
- Поддержка всех tuple-операций: индексация, распаковка, сравнение;
- Метод asdict() — для превращения в словарь;
- Метод
replace() — для создания новой копии с измененными полями.

Пример:

updated_place = place._replace(name='Office')

print(place.name) # 'Home'
print(updated_place.name) # 'Office'


А вот превращение в словарь удобно, если нужно, скажем, сериализовать:

print(place._asdict())
# {'name': 'Home', 'latitude': 55.750446, 'longitude': 37.617494}


🧩 Когда использовать?

Используй namedtuple, когда:

1. У объекта фиксированное количество атрибутов;
2. Ты хочешь неизменяемые структуры;
3. Нужна читаемость при минимальных затратах памяти.

Для mutable-объектов лучше подойдет dataclass, но это уже другая история.

🤹 Чуть больше магии

namedtuple позволяет указывать значения по умолчанию (не напрямую, но можно немного схитрить):

Color = namedtuple('Color', ['r', 'g', 'b'], defaults=[0, 0, 0])

gray = Color()
print(gray) # Color(r=0, g=0, b=0)


Эта фича доступна, начиная с Python 3.7.

🔚 Итоги

Если тебе нужно структурировать данные, но не хочется писать полноценный класс — namedtuple будет твоим лучшим другом. Он компактен, читаем и быстр. Маленький герой большого кода.

Используй силу именованных кортежей и пиши код, который не только работает, но и радует глаз.
👍1
Как настроить FTP соединение с использованием модуля ftplib
Привет! Сегодня мы поговорим о модуле ftplib — простом, но полезном инструменте Python для работы с FTP. Вы сможете подключиться к удалённому серверу, скачать или загрузить файлы — и всё это всего за пару строк кода. Поехали!

Модуль ftplib входит в стандартную библиотеку Python, так что ничего дополнительно устанавливать не нужно. Давайте сразу начнем с базового подключения.

## Подключаемся к FTP-серверу

Для начала, создадим соединение и получим список файлов:

from ftplib import FTP

ftp = FTP('ftp.example.com') # Адрес сервера
ftp.login(user='username', passwd='password')

ftp.cwd('/path/to/directory') # Переход в нужную директорию
files = ftp.nlst() # Получаем список файлов
print(files)

ftp.quit()


Метод login() используется для авторизации. Если сервер поддерживает анонимный доступ, просто вызовите ftp.login() без параметров. Метод nlst() возвращает список имен файлов в текущей директории.

## Скачиваем файл

Хотите скачать файл — скажем, data.txt? Легко:

with open('data.txt', 'wb') as f:
ftp.retrbinary('RETR data.txt', f.write)


Метод retrbinary() хорош для двоичных данных (например, изображений). Если вы уверены, что работаете с текстом, можно использовать retrlines():

ftp.retrlines('RETR readme.txt', lambda line: print(">>", line))


## Загружаем файл

Теперь — наоборот: загрузим файл на сервер.

with open('upload.txt', 'rb') as f:
ftp.storbinary('STOR upload.txt', f)


Метод storbinary() отправляет двоичный файл на сервер. Если нужно передать файл построчно, используйте storlines().

## Полезные фишки

- ftp.cwd(path) — смена директории на сервере.
- ftp.mkd(dirname) и ftp.rmd(dirname) — создать и удалить директорию.
- ftp.delete(filename) — удалить файл.
- ftp.rename(old, new) — переименовать файл или переместить.

Пример: создадим папку и загрузим туда файл.

ftp.mkd('new_folder')
ftp.cwd('new_folder')

with open('photo.jpg', 'rb') as f:
ftp.storbinary('STOR photo.jpg', f)


## Немного безопасности

FTP — это не самый защищённый протокол. Данные передаются в открытом виде, без шифрования. Если работаете с чувствительной информацией — рассмотрите ftplib.FTP_TLS, чтобы использовать FTPS.

from ftplib import FTP_TLS

ftp = FTP_TLS('secure.example.com')
ftp.login('user', 'password')
ftp.prot_p() # Включаем защиту данных


## В заключение

Модуль ftplib — это отличный способ автоматизировать работу с файлами на удалённых серверах. Он незаменим, если вы, например, хотите написать скрипт, который каждый день сохраняет бэкапы или забирает отчеты с FTP-серверов. Всё просто: минимум кода, максимум полезности.

До встречи в следующих постах!
Ваш Иван 🐍
Изучение параметров командной строки: модуль argparse в действии
Привет! На связи Иван, и сегодня поговорим о том, как научить свои скрипты понимать команды из терминала. Представь: ты написал крутую утилиту, и теперь хочешь запускать её с разными параметрами, а не каждый раз менять код или жонглировать input(). На помощь приходит модуль argparse — встроенный в Python инструмент для парсинга аргументов командной строки.

Никакой магии, только понятный и мощный API. Давайте разберёмся, как он работает на практике.

Начнем с мини-примера:

import argparse

parser = argparse.ArgumentParser(description='Simple greeting script')
parser.add_argument('--name', type=str, help='Name of the person')
args = parser.parse_args()

print(f"Hello, {args.name}!")


Попробуй теперь вызвать скрипт из консоли так:

python script.py --name Alice


И получишь: Hello, Alice!

Что здесь происходит?

- ArgumentParser запускает “приёмную кампанию” для аргументов.
- add_argument() указывает, что мы ждём аргумент --name, и какого он типа.
- parse_args() превращает пользовательский ввод в объект с атрибутами.

Теперь усилим пример. Добавим обязательный аргумент и флаг:

parser.add_argument('filename', type=str, help='Path to the input file')
parser.add_argument('--verbose', action='store_true', help='Enable verbose mode')


Команды:

python script.py data.txt --verbose


Здесь filename — позиционный аргумент (обязателен), а --verbose — флаг (включается, если указан).

Тебе не нужно писать код для проверки: есть ли аргументы, правильно ли указаны — за это отвечает argparse. Даже help-меню (да, оно генерируется само!) можно получить так:

python script.py --help


Вы получите подробную справку автоматически. Удобно? Очень.

👀 А теперь пример посложнее — калькулятор с операцией и числами:

parser = argparse.ArgumentParser(description='Simple calculator')
parser.add_argument('operation', choices=['add', 'sub'], help='Operation to perform')
parser.add_argument('x', type=int, help='First number')
parser.add_argument('y', type=int, help='Second number')
args = parser.parse_args()

if args.operation == 'add':
result = args.x + args.y
else:
result = args.x - args.y

print(f"Result: {result}")


Вызов:

python calc.py add 3 7
# Выведет: Result: 10


А если указать что-то кроме add или sub — argparse не даст запустить скрипт.

Вот за что я люблю этот модуль — минимум кода, максимум пользы. У него есть и более продвинутые возможности: группы аргументов, парсинг вложенных команд, типы вроде float или datetime. Для больших CLI-добавлений можно использовать argparse в связке с модулями subparsers или даже перейти на click, но это уже другая история.

Если ты хочешь превратить свой скрипт в полноценный инструмент командной строки — начинай с argparse. Он встроен, прост и отлично масштабируется.

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

Когда мы говорим «состояние приложения», мы подразумеваем набор параметров, описывающих его текущую "жизнь". Если подходить к этому хаотично — создавая глобальные переменные или передавая «состояние» вручную в каждую функцию, — приложение быстро превратится в кошмар для сопровождения.

Вот тут и приходят на помощь классы.

Посмотрим на простой пример. Допустим, мы разрабатываем текстовый редактор:

class TextEditorState:
def __init__(self):
self.filename = None
self.content = ""
self.modified = False

def load_file(self, filename):
with open(filename, "r", encoding="utf-8") as f:
self.content = f.read()
self.filename = filename
self.modified = False

def update_content(self, new_content):
self.content = new_content
self.modified = True

def save(self):
if self.filename:
with open(self.filename, "w", encoding="utf-8") as f:
f.write(self.content)
self.modified = False


Теперь у нас есть полноценный контейнер состояния редактора. Всё, что может происходить: загрузка файла, изменения, сохранение — оформлено методами класса. И главное, состояние (content, filename, modified) всегда у нас под контролем и в одном месте.

Но зачем вообще класс, если можно просто передавать словарь?

Во-первых, классы позволяют инкапсулировать поведение: вы определяете не только данные, но и то, как с ними можно работать. Во-вторых — читаемость, масштабируемость, интеграция с типизацией. Это особенно ценно, когда приложение растёт.

Давайте усложним задачу. Создадим что-нибудь вроде простого игрового состояния:

class GameState:
def __init__(self):
self.level = 1
self.score = 0
self.inventory = []

def next_level(self):
self.level += 1

def add_score(self, points):
self.score += points

def add_item(self, item):
self.inventory.append(item)

def reset(self):
self.level = 1
self.score = 0
self.inventory.clear()


Теперь GameState знает, как себя "вести", когда игра запускается, когда игрок переходит на следующий уровень или завершает сессию. Такой подход прекрасно масштабируется: можно добавить сохранение/загрузку в JSON, можно сделать отдельные состояния для игрока, врагов, меню — и всё это будет изолировано и логично.

Небольшой бонус — использование dataclass:

from dataclasses import dataclass, field

@dataclass
class SessionState:
user_id: int
is_authenticated: bool = False
preferences: dict = field(default_factory=dict)


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

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

До встречи!
– Иван 👨‍💻
🔥3
Создание простой блога с использованием Markdown и Flask
Привет! Сегодня мы сделаем кое-что особенно полезное: создадим простой блог с помощью Flask — лёгкого микрофреймворка — и Markdown, удобного формата для написания текста с элементами разметки. Это отличный проект для начинающих: быстро, понятно и наглядно.

Почему Markdown? Потому что он интуитивно понятен. Вы просто пишете текст с легкой разметкой (заголовки, списки, ссылки), а потом через Python превращаете это в полноценную HTML-страницу. Удобно и красиво!

Начнем с простого примера структуры папок:

simple_blog/
├── app.py
├── posts/
│ ├── first_post.md
│ └── second_post.md
├── templates/
│ ├── base.html
│ └── post.html


Установим необходимые модули:

pip install flask markdown


Теперь — немного кода. Файл app.py:

import os
from flask import Flask, render_template, abort
import markdown

app = Flask(__name__)
POSTS_DIR = 'posts'

def get_post_content(filename):
path = os.path.join(POSTS_DIR, filename)
if not os.path.exists(path):
return None
with open(path, 'r', encoding='utf-8') as f:
return markdown.markdown(f.read())

@app.route('/')
def index():
posts = [f[:-3] for f in os.listdir(POSTS_DIR) if f.endswith('.md')]
return render_template('base.html', posts=posts)

@app.route('/post/<name>')
def post(name):
html_content = get_post_content(f"{name}.md")
if html_content is None:
abort(404)
return render_template('post.html', content=html_content, title=name)


Темплейт base.html — список постов:

<!doctype html>
<html>
<head><title>Simple Blog</title></head>
<body>
<h1>My Simple Blog</h1>
<ul>
{% for name in posts %}
<li><a href="{{ url_for('post', name=name) }}">{{ name }}</a></li>
{% endfor %}
</ul>
</body>
</html>


Темплейт post.html — отображение Markdown:

<!doctype html>
<html>
<head><title>{{ title }}</title></head>
<body>
<a href="{{ url_for('index') }}">← Back to blog</a>
<hr>
{{ content | safe }}
</body>
</html>


Пример Markdown-файла posts/first_post.md:

# Привет, мир!

Это мой первый пост в блоге на **Flask** и _Markdown_.

- Я пишу текст в Markdown
- Flask превращает его в HTML
- Всё просто!


На этом и всё! Вы получаете минималистичный блог, в который удобно добавлять посты, просто сохраняя их в виде .md-файлов. Нет базы данных, нет тяжелых CMS — только Flask, Markdown и немного магии Python.

Удачи в кодинге!
— Иван.
🔥4👍2
Обработка файлов CSV с использованием модуля csv
📁 CSV-файлы и модуль csv: удобный вход в мир данных на Python
Привет! С вами Иван — и сегодня мы поговорим о том, как Python помогает обращаться с CSV-файлами с лёгкостью и грацией библиотекаря, разбирающего карточный каталог.

CSV — это табличные данные в виде обычного текста, разделённого запятыми (Comma-Separated Values). Это один из самых популярных и доступных форматов обмена данными между сервисами, программами и людьми. Работаешь с Excel? Экспортируешь из Google Sheets? Загружаешь выгрузку из CRM? Почти наверняка — это CSV.

В Python для работы с такими файлами есть мощный встроенный модуль — csv. Он не требует отдельной установки и готов к работе сразу после установки Python. Давайте взглянем, как с ним подружиться.

📦 Чтение CSV-файлов

Начнём с базы. Предположим, у нас есть файл data.csv:

name,age,city
Alice,30,New York
Bob,25,London
Charlie,35,Berlin


Прочитаем его, используя csv.reader:

import csv

with open('data.csv', newline='') as csvfile:
reader = csv.reader(csvfile)
for row in reader:
print(row)


Вывод:

['name', 'age', 'city']
['Alice', '30', 'New York']
['Bob', '25', 'London']
['Charlie', '35', 'Berlin']


Каждая строка CSV превращается в список строк. Просто и удобно!

Но чаще хочется работать с данными по ключам, а не по индексам. На помощь приходит csv.DictReader:

import csv

with open('data.csv', newline='') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
print(row['name'], 'from', row['city'])


Вывод:

Alice from New York
Bob from London
Charlie from Berlin


Такой способ уже больше похож на работу с JSON или базой данных.

📝 Запись CSV-файлов

Допустим, теперь ты хочешь сохранить обработанные данные. Для этого используется csv.writer:

import csv

data = [
['product', 'price'],
['laptop', '1200'],
['phone', '800'],
['tablet', '500']
]

with open('products.csv', 'w', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerows(data)


Или, с заголовками и словарями:

import csv

data = [
{'product': 'laptop', 'price': 1200},
{'product': 'phone', 'price': 800},
{'product': 'tablet', 'price': 500},
]

with open('products_dict.csv', 'w', newline='') as csvfile:
fieldnames = ['product', 'price']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

writer.writeheader()
for item in data:
writer.writerow(item)


Оба способа сохранят таблицу в читаемом виде, которую можно открыть даже в Excel.

🔧 Немного тонкостей

- Модуль csv справляется не только с запятыми — можно задать любой разделитель через параметр delimiter.
- Не забудь про newline='' при открытии файла — это нужно для правильной работы на Windows.
- Если ты хочешь обрабатывать большой файл построчно — модуль csv делает это достаточно эффективно, не загружая весь файл в память.

🎁 Вывод

csv — один из тех модулей Python, про который можно забыть… а потом снова открыть, порадоваться, и не думать о ручном разборе текста. Он удобен, предсказуем и отличный старт для тех, кто только начинает работать с данными.

Дальше будет интереснее — впереди pandas, но csv — отличный первый шаг.

До связи, Иван.
👍3
Работа с файловой системой: поиск и управление файлами с help модуля os
Привет! С вами Иван, и сегодня поговорим о работе с файловой системой на Python. Если вы думаете, что модуль os — это скучный рудимент из древних Python-эпох, то вы сильно заблуждаетесь. Этот модуль — настоящая швейцарская армия программиста: он позволяет шастать по директориям, искать, удалять, переименовывать и создавать файлы, словно вы — повелитель вашей файловой империи. Давайте нырнем в эту тему вместе.

Начнем с главного — исследования текущей директории:

import os

# Получаем текущую рабочую директорию
current_dir = os.getcwd()
print(f"Current working directory: {current_dir}")


Теперь пробежимся по файлам и папкам:

for item in os.listdir(current_dir):
item_path = os.path.join(current_dir, item)
if os.path.isfile(item_path):
print(f"File: {item}")
elif os.path.isdir(item_path):
print(f"Directory: {item}")


Элементарно, Ватсон? А вот теперь интереснее.

Допустим, вам нужно найти все файлы с расширением .txt в какой-нибудь глубокой-длинной папке. Для этого отлично подходит os.walk:

search_root = "/path/to/search"

for root, dirs, files in os.walk(search_root):
for file in files:
if file.endswith(".txt"):
print(f"Found: {os.path.join(root, file)}")


os.walk рекурсивно обходит все директории, будто у него бесконечные силы. Отличный инструмент для файловой разведки.

А как насчет создания и удаления директорий?

new_dir = os.path.join(current_dir, "new_folder")

if not os.path.exists(new_dir):
os.mkdir(new_dir)
print(f"Created directory: {new_dir}")
else:
print(f"Directory already exists: {new_dir}")

# Удаление
os.rmdir(new_dir)
print(f"Deleted directory: {new_dir}")


Важно: os.rmdir удалит папку только если она пустая. Если внутри что-то есть — получите ошибку. Для сложных случаев уже нужен модуль shutil, но об этом — в другой раз.

И на десерт — переименование файла:

old_name = os.path.join(current_dir, "old_file.txt")
new_name = os.path.join(current_dir, "new_file.txt")

if os.path.exists(old_name):
os.rename(old_name, new_name)
print(f"Renamed to: {new_name}")


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

Да, модуль os выглядит скромно, но за его простым интерфейсом скрываются мощные возможности. Умея пользоваться im, вы сможете автоматизировать многое: от сортировки загрузок до сканирования большого дерева проектов — всё в пределах нескольких строк.

Пишите Python-скрипты, которые делают рутину за вас. И пусть файловая система подчинится вам!
3👍1
Как использовать Python для периодических задач с помощью модуля sched
Привет! С вами Иван — и сегодня я расскажу, как с помощью Python и стандартного модуля sched решать задачи, которые должны выполняться периодически. Даже если вы только начинаете изучать язык, этот инструмент может значительно облегчить вашу жизнь.

Вы наверняка сталкивались с ситуациями, когда нужно что-то делать через определённые интервалы времени: например, проверять обновления на сайте, делать резервные копии или отправлять уведомления. Обычно на помощь приходит time.sleep или даже многопоточность, но в Python уже есть гораздо более тонкое и приятное средство — модуль sched.

## В чём суть sched?

Модуль sched реализует планировщик событий. Вы создаёте объект планировщика, добавляете в него задачи, указываете время запуска — и планировщик сам их аккуратно "отпускает в бой".

Вот базовый пример:

import sched
import time

def print_message(name):
print(f"Hello, {name}! The time is {time.ctime()}")

scheduler = sched.scheduler(time.time, time.sleep)
scheduler.enter(3, 1, print_message, argument=("Ivan",))
scheduler.enter(6, 1, print_message, argument=("Pythonista",))
scheduler.run()


Этот код выведет приветствие сначала через 3 секунды, затем через 6 секунд от запуска. Всё просто: enter — добавить задачу через указанное время, run — начать выполнение.

## Как сделать периодическую задачу?

Секрет тут в самой функции-обработчике: она добавляет себя обратно в планировщик. Пример создания "бесконечного повторения" раз в 5 секунд:

import sched
import time

def periodic_task(scheduler, interval):
print(f"Periodic task runs at {time.ctime()}")
scheduler.enter(interval, 1, periodic_task, (scheduler, interval))

scheduler = sched.scheduler(time.time, time.sleep)
scheduler.enter(0, 1, periodic_task, (scheduler, 5))
scheduler.run()


Функция periodic_task при каждом вызове снова добавляет себя в расписание через 5 секунд — и так до бесконечности (или пока не остановите программу).

## Особенности и когда использовать

sched отлично подходит для простых задач планирования в одном потоке. Если у вас десятки тысяч событий или критична высокая точность — лучше смотрите в сторону более продвинутых библиотек (например, APScheduler или Celery). Но для домашних проектов и скриптов эта маленькая "швейцарская армия" планирования будет как нельзя кстати.

Подытожим: модуль sched — это минималистичный, но удобный планировщик для несложных задач во времени. А если хочется почувствовать себя дирижёром событий — стоит попробовать!

На связи был Иван. Экспериментируйте с Python — он полон приятных сюрпризов!
👍1