🐛 Типичные ошибки

⚡ Топ-3 ошибки

  • Путать индексы sys.argv: sys.argv[0] — имя скрипта, первый аргумент — sys.argv[1].
  • Пытаться удалить непустую директорию через os.rmdir: она удаляет только пустые папки.
  • Собирать пути вручную через "/" или "\\" вместо os.path.join.

Ошибка 1. Неправильная индексация sys.argv

Первый элемент sys.argv — это имя запущенного скрипта. Аргументы пользователя начинаются с индекса 1.

# ❌ Неправильно: пытаемся прочитать аргумент с индекса 0
import sys
first_arg = sys.argv[0]  # это имя скрипта, не пользовательский аргумент

# ✅ Правильно
import sys
if len(sys.argv) > 1:
    first_arg = sys.argv[1]
else:
    print("Аргумент не передан.")

Ошибка 2. Удаление непустой директории через os.rmdir

os.rmdir удаляет только пустые директории. Если в папке есть файлы, будет ошибка OSError.

# ❌ Ошибка, если в папке есть файлы
os.rmdir("logs")

# ✅ Проверяем, что папка пуста, или удаляем содержимое сначала
import os

for item in os.listdir("logs"):
    item_path = os.path.join("logs", item)
    if os.path.isfile(item_path):
        os.remove(item_path)

os.rmdir("logs")

Для рекурсивного удаления непустых папок в стандартной библиотеке есть shutil.rmtree, но этот модуль не разбирается в исходной лекции.

Ошибка 3. Ручная сборка пути через слеши

Разделитель путей различается в Windows (\) и Linux/macOS (/). Ручная сборка ломается при переносе кода.

# ❌ Неправильно
path = folder + "/" + file_name       # плохо на Windows
path = folder + "\\" + file_name      # плохо на Linux / macOS

# ✅ Правильно
import os
path = os.path.join(folder, file_name)

Ошибка 4. Лишние проверки и состояние гонки

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

# ❌ Проверка + действие — неатомарно
if os.path.exists("data.txt"):
    with open("data.txt", "r") as file:
        content = file.read()

# ✅ Лучше: обработать исключение
try:
    with open("data.txt", "r") as file:
        content = file.read()
except FileNotFoundError:
    content = ""

Ошибка 5. Забыть проверить тип объекта

os.listdir возвращает и файлы, и папки. Если предполагать, что все элементы — файлы, можно получить ошибку.

# ❌ Ошибка, если попадётся папка
for item in os.listdir("."):
    with open(item, "r") as file:  # OSError на директории
        print(file.read())

# ✅ Правильно
for item in os.listdir("."):
    if os.path.isfile(item):
        with open(item, "r", encoding="utf-8") as file:
            print(file.read())

Ошибка 6. Забыть импортировать sys

Часто в примерах с sys.argv забывают добавить import sys, и программа падает с NameError.

# ❌ Неправильно
if len(sys.argv) != 2:  # NameError: name 'sys' is not defined
    sys.exit(1)

# ✅ Правильно
import sys

if len(sys.argv) != 2:
    sys.exit(1)

Ошибка 7. Использовать относительные пути без понимания CWD

Текущая рабочая директория зависит от того, откуда запущен скрипт. Если запускать файл из другой папки, относительные пути могут перестать работать.

# ✅ Надёжнее: привязаться к расположению самого скрипта
import os

script_dir = os.path.dirname(os.path.abspath(__file__))
data_path = os.path.join(script_dir, "data", "input.txt")

Такой подход работает независимо от того, из какой директории запущен скрипт.