🏠 Домашнее задание

⚡ Суть задания

Создать два миксина для воспроизведения аудио и видео, а затем два устройства: MediaPlayer (только аудио) и Laptop (аудио и видео). Миксины должны проверять наличие нужных полей через hasattr и выбрасывать AttributeError, если поле отсутствует.

Результат: файл media_player.py, который можно запустить и увидеть ожидаемый вывод.

📋 Формулировка задания

Исходное задание из LMS:

  1. Воспроизведение мультимедиа. Создайте два класса:
    • AudioFileMixin — требует наличие поля audio_tracks (список треков). Метод play_audio() выводит:
      Воспроизведение аудио для <НазваниеКласса>:, затем каждый трек с новой строки.
    • VideoFileMixin — требует наличие поля video_files (список видео). Метод play_video() выводит:
      Воспроизведение видео для <НазваниеКласса>:, затем каждое видео с новой строки.
    Если нужное поле отсутствует — выбрасывайте AttributeError.
  2. Устройства. Создайте два класса:
    • MediaPlayer — поддерживает только аудио. Принимает список треков.
    • Laptop — поддерживает аудио и видео. Принимает списки треков и видео.
    Проверьте работу классов, вызвав методы воспроизведения.

🔧 Шаг 0. Подготовка окружения

Перед началом работы над любым заданием курса нужно настроить окружение. Эти шаги одинаковы для всех уроков.

📁 Структура репозитория: мы используем один репозиторий для всех практических работ курса. Это удобнее, чем десятки отдельных репозиториев: общий .gitignore, единая история, легко переключаться между уроками.
1

Создайте (или откройте) рабочую папку

В VS Code нажмите Ctrl+K Ctrl+O → выберите или создайте папку python-fundamentals-practice. Это будет корень вашего учебного репозитория.

# Или в терминале VS Code (Ctrl + `):
mkdir python-fundamentals-practice
cd python-fundamentals-practice
2

Инициализируйте Git-репозиторий (один раз)

git init

echo "# Python Fundamentals — Практические работы" > README.md
echo "venv/" > .gitignore
echo "__pycache__/" >> .gitignore
echo "*.pyc" >> .gitignore
echo ".env" >> .gitignore

git add README.md .gitignore
git commit -m "init: базовая структура репозитория"
3

Создайте папку для текущего урока

mkdir -p lesson-72
cd lesson-72
4

Создайте виртуальное окружение (venv)

# Windows
python -m venv venv
venv\Scripts\activate

# Mac / Linux
python3 -m venv venv
source venv/bin/activate

После активации в начале строки терминала появится (venv).

5

Создайте ветку для задания

cd ..
git checkout -b lesson/72-multiple-inheritance

# Если настроен удалённый репозиторий:
git push -u origin lesson/72-multiple-inheritance

🛠️ Шаги выполнения задания

1

Создайте файл media_player.py

В папке lesson-72 создайте файл media_player.py.

2

Реализуйте миксины AudioFileMixin и VideoFileMixin

Каждый миксин должен проверять наличие нужного поля через hasattr и выводить заголовок с именем класса и список элементов.

3

Реализуйте классы MediaPlayer и Laptop

MediaPlayer наследует только AudioFileMixin. Laptop наследует оба миксина. В __init__ сохраните переданные списки в поля audio_tracks и video_files.

4

Проверьте работу

Создайте объекты с тестовыми данными и вызовите методы воспроизведения.

✅ Полное решение

Ниже приведено полное решение задания. Совет: попробуйте выполнить самостоятельно, прежде чем смотреть ответ.

class AudioFileMixin:
    def play_audio(self) -> None:
        if not hasattr(self, "audio_tracks"):
            raise AttributeError("Отсутствует поле audio_tracks")
        print(f"Воспроизведение аудио для {self.__class__.__name__}:")
        for track in self.audio_tracks:
            print(track)


class VideoFileMixin:
    def play_video(self) -> None:
        if not hasattr(self, "video_files"):
            raise AttributeError("Отсутствует поле video_files")
        print(f"Воспроизведение видео для {self.__class__.__name__}:")
        for video in self.video_files:
            print(video)


class MediaPlayer(AudioFileMixin):
    def __init__(self, audio_tracks: list[str]) -> None:
        self.audio_tracks = audio_tracks


class Laptop(AudioFileMixin, VideoFileMixin):
    def __init__(self, audio_tracks: list[str], video_files: list[str]) -> None:
        self.audio_tracks = audio_tracks
        self.video_files = video_files


# Проверка
if __name__ == "__main__":
    tracks = ["track1.mp3", "track2.mp3"]
    movies = ["movie.mp4", "trailer.mov"]

    player = MediaPlayer(tracks)
    player.play_audio()

    laptop = Laptop(tracks, movies)
    laptop.play_audio()
    laptop.play_video()

Ожидаемый вывод:

Воспроизведение аудио для MediaPlayer:
track1.mp3
track2.mp3
Воспроизведение аудио для Laptop:
track1.mp3
track2.mp3
Воспроизведение видео для Laptop:
movie.mp4
trailer.mov

🧪 Как проверить решение

  1. Активируйте venv: venv\Scripts\activate (Windows) или source venv/bin/activate (Mac/Linux).
  2. Запустите файл: python lesson-72/media_player.py.
  3. Убедитесь, что в терминале нет ошибок и вывод совпадает с ожидаемым.
  4. Попробуйте создать объект без нужного поля и убедитесь, что возникает AttributeError.

🐛 Отладка в VS Code

Если что-то не работает:

  1. Поставьте точку останова (breakpoint) в __init__ или play_audio.
  2. Нажмите F5 или выберите «Run → Start Debugging».
  3. В панели Debug посмотрите значения self.audio_tracks и self.video_files.
  4. Проверьте Terminal на наличие traceback — Python показывает номер строки с ошибкой.

💾 Сохранение работы

git add lesson-72/
git commit -m "lesson-72: multiple inheritance, mixins and media player"
git push

💡 Советы и типичные ошибки

  • Убедитесь, что venv активирован перед запуском.
  • Не коммитьте папку venv/ — она указана в .gitignore.
  • Миксины не должны иметь собственного __init__, иначе их сложно комбинировать.
  • Используйте hasattr для проверки полей, а не try/except AttributeError при обращении.
  • Для имени класса в выводе используйте self.__class__.__name__.
Проверить по документации: аннотации типов в примере выходят за рамки исходного задания. Подробнее см. typing и PEP 484.