Разработка приложения для работы с файлами на Python

Раздел: Python -> IDE и редакторы

Основные подходы к созданию файлового менеджера

Как создать консольный файловый менеджер с базовыми операциями?

Представленный ниже код использует модуль pathlib для удобной работы с путями. Основная идея: реализовать циклическое меню с командами: ls (список), cd (смена директории), cp (копирование), mv (перемещение), rm (удаление). Для каждой команды добавлена обработка ошибок.


import pathlib, shutil, sys

def main():
    current = pathlib.Path.cwd()
    while True:
        print(f"Текущая папка: {current}")
        command = input("Введите команду: ").strip().split()
        if not command:
            continue
        cmd = command[0].lower()
        try:
            if cmd == 'ls':
                for item in current.iterdir():
                    print(item.name)
            elif cmd == 'cd':
                target = command[1] if len(command)>1 else '.'
                new = current / target
                new = new.resolve()
                if new.is_dir():
                    current = new
                else:
                    print("Ошибка: не папка")
            elif cmd == 'cp':
                src, dst = command[1], command[2]
                src_path = current / src
                dst_path = current / dst
                if src_path.is_file():
                    shutil.copy2(src_path, dst_path)
                else:
                    shutil.copytree(src_path, dst_path)
            elif cmd == 'mv':
                src, dst = command[1], command[2]
                shutil.move(str(current / src), str(current / dst))
            elif cmd == 'rm':
                target = command[1]
                path = current / target
                if path.is_file():
                    path.unlink()
                else:
                    shutil.rmtree(path)
            elif cmd == 'exit':
                sys.exit(0)
        except Exception as e:
            print(f"Ошибка: {e}")

Python packaging tools (python packaging tools (инструменты сборки))

Пояснения: pathlib предоставляет объекты Path, которые упрощают операции. shutil используется для копирования и перемещения. В цикле обрабатываются исключения, чтобы программа не падала при ошибках доступа или неверных путях.

Типичные проблемы:

  • Пробелы в именах файлов - метод split() разбивает ввод по пробелам. Решение: использовать input() без split или парсить с учётом кавычек.
  • Права доступа - исключение PermissionError. Обрабатывается общим except.
  • Кодировка вывода - в Windows может возникнуть проблема с кириллицей. Решение: установить кодировку консоли (chcp 65001) или использовать sys.stdout.reconfigure.

Как реализовать файловый менеджер с графическим интерфейсом на tkinter?

Пример ниже создаёт окно с Treeview для отображения файлов, кнопками для навигации и операций. Используется встроенный модуль tkinter и ttk.


import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import pathlib, shutil

class FileManager:
    def __init__(self, root):
        self.root = root
        self.root.title('Файловый менеджер')
        self.current_path = pathlib.Path.home()
        self.create_widgets()
        self.refresh()

    def create_widgets(self):
        self.tree = ttk.Treeview(self.root, columns=('Name','Size','Type'), show='headings')
        self.tree.heading('Name', text='Имя')
        self.tree.heading('Size', text='Размер')
        self.tree.heading('Type', text='Тип')
        self.tree.pack(fill=tk.BOTH, expand=True)
        btn_frame = tk.Frame(self.root)
        btn_frame.pack()
        tk.Button(btn_frame, text='Вверх', command=self.go_up).pack(side=tk.LEFT)
        tk.Button(btn_frame, text='Удалить', command=self.delete_item).pack(side=tk.LEFT)

    def go_up(self):
        self.current_path = self.current_path.parent
        self.refresh()

    def refresh(self):
        for i in self.tree.get_children():
            self.tree.delete(i)
        try:
            for item in self.current_path.iterdir():
                name = item.name
                size = ''
                typ = 'Папка' if item.is_dir() else 'Файл'
                if item.is_file():
                    size = str(item.stat().st_size) + ' B'
                self.tree.insert('', tk.END, values=(name, size, typ))
        except PermissionError:
            messagebox.showerror('Ошибка', 'Нет доступа к папке')

    def delete_item(self):
        selected = self.tree.selection()
        if selected:
            name = self.tree.item(selected[0], 'values')[0]
            path = self.current_path / name
            if messagebox.askyesno('Подтверждение', f'Удалить {name}?'):
                try:
                    if path.is_dir():
                        shutil.rmtree(path)
                    else:
                        path.unlink()
                    self.refresh()
                except Exception as e:
                    messagebox.showerror('Ошибка', str(e))

root = tk.Tk()
app = FileManager(root)
root.mainloop()

Python online код (онлайн редактор python)

Пояснения: Treeview отображает данные в табличном виде. pathlib.Path.iterdir() получает содержимое папки. При удалении выводится диалог подтверждения. Проблемы: быстродействие при большом количестве файлов (решение - загружать постранично, например через виртуальное дерево).

Как упростить создание графического файлового менеджера с PySimpleGUI?


import PySimpleGUI as sg
import pathlib, shutil

layout = [
    [sg.Text('Текущая папка'), sg.Input('', key='-PATH-'), sg.FolderBrowse('Обзор')],
    [sg.Listbox(values=[], key='-FILES-', size=(60,20))],
    [sg.Button('Копировать'), sg.Button('Удалить'), sg.Button('Выход')]
]
window = sg.Window('Файловый менеджер', layout)
current = pathlib.Path.cwd()
while True:
    event, values = window.read()
    if event in (sg.WIN_CLOSED, 'Выход'):
        break
    if event == 'Обзор':
        current = pathlib.Path(values['-PATH-'])
    try:
        files = [p.name for p in current.iterdir()]
        window['-FILES-'].update(files)
    except Exception as e:
        sg.popup_error('Ошибка', str(e))
window.close()

Find python script (поиск python скрипта)

PySimpleGUI значительно сокращает код. Однако имеет ограничения по настройке внешнего вида. Для простого файлового менеджера такой подход оправдан.

Как организовать файловый менеджер через веб-интерфейс?


from flask import Flask, render_template_string, request
import pathlib, shutil

app = Flask(__name__)
BASE = pathlib.Path.cwd()

@app.route('/')
def index():
    path = request.args.get('path', '.')
    full = (BASE / path).resolve()
    try:
        items = [{'name': p.name, 'relpath': p.relative_to(BASE).as_posix()} for p in full.iterdir()]
    except PermissionError:
        items = []
    return render_template_string('''
        

{{ path }}

{% for item in items %} {% endfor %} ''', path=path, items=items) if __name__ == '__main__': app.run(debug=True)

Веб-менеджер удобен для удаленного доступа. Требуется тщательная валидация путей и ограничение доступа во избежание уязвимостей (например, path traversal).

- File manager python (файловый менеджер на python)
- Microsoft vs python (python в visual studio)
- Microsoft code python (настройка python в visual studio code)

Расширенные примеры и нестандартные сценарии

Асинхронное копирование файлов с asyncio

Когда требуется скопировать множество больших файлов, асинхронный подход позволяет не блокировать основной поток. Используется библиотека aiofiles и asyncio.

Пример

import asyncio
import aiofiles
import aiofiles.os
import pathlib

async def copy_file(src, dst):
    async with aiofiles.open(src, 'rb') as fsrc:
        async with aiofiles.open(dst, 'wb') as fdst:
            while True:
                chunk = await fsrc.read(65536)
                if not chunk:
                    break
                await fdst.write(chunk)

async def main(src_dir, dst_dir):
    src = pathlib.Path(src_dir)
    dst = pathlib.Path(dst_dir)
    tasks = []
    for item in src.iterdir():
        if item.is_file():
            tasks.append(copy_file(item, dst / item.name))
    await asyncio.gather(*tasks)

asyncio.run(main('/source', '/dest'))
Результат: все файлы из /source скопированы в /dest асинхронно.
(Выполнение завершено без вывода, так как функция ничего не печатает.)

Отслеживание изменений в файловой системе с watchdog

Модуль watchdog позволяет наблюдать за изменениями в директории и реагировать на них.

Пример

from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import time

class MyHandler(FileSystemEventHandler):
    def on_modified(self, event):
        print(f'Изменен: {event.src_path}')
    def on_created(self, event):
        print(f'Создан: {event.src_path}')

path = '.'
observer = Observer()
observer.schedule(MyHandler(), path, recursive=False)
observer.start()
try:
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    observer.stop()
observer.join()
При создании или изменении файла в текущей папке выводится соответствующее сообщение.

Работа с архивами: упаковка и распаковка zip

Пример

import zipfile
import pathlib

def create_zip(source_dir, output_zip):
    with zipfile.ZipFile(output_zip, 'w', zipfile.ZIP_DEFLATED) as zf:
        for file in pathlib.Path(source_dir).rglob('*'):
            zf.write(file, file.relative_to(source_dir))

def extract_zip(zip_path, extract_dir):
    with zipfile.ZipFile(zip_path, 'r') as zf:
        zf.extractall(extract_dir)

create_zip('./my_folder', './backup.zip')
extract_zip('./backup.zip', './restored')
После выполнения появится backup.zip, а затем папка restored с содержимым.

Рекурсивный поиск файлов по маске

Пример

import pathlib

pattern = '*.py'
found = list(pathlib.Path('.').rglob(pattern))
for f in found:
    print(f.relative_to('.'))
Вывод всех файлов .py в текущем каталоге и подкаталогах.

Пакетное переименование файлов с использованием регулярных выражений

Пример

import pathlib
import re

def rename_files(directory, pattern, replacement):
    for file in pathlib.Path(directory).iterdir():
        if file.is_file():
            new_name = re.sub(pattern, replacement, file.name)
            if new_name != file.name:
                file.rename(file.parent / new_name)

rename_files('./', r'\s+', '_')
Все файлы в текущей папке с пробелами в имени переименуются: пробелы заменяются на подчеркивание.

Хеширование файлов (MD5) для проверки целостности

Пример

import hashlib

def md5_hash(file_path):
    h = hashlib.md5()
    with open(file_path, 'rb') as f:
        for chunk in iter(lambda: f.read(4096), b''):
            h.update(chunk)
    return h.hexdigest()

print(md5_hash('test.txt'))
d41d8cd98f00b204e9800998ecf8427e  (пример для пустого файла)

Файловый менеджер на Python - comments

En
File manager python (python)