Как определить, когда нужно использовать рекурсию, а когда лучше обойтись без нее?

Как настроить сериализацию в JSON для библиотеки книг таким образом, чтобы каждая книга содержала ссылку на полку, на которой она находится, без списка книг на данной полке, и при сериализации каждой книги в представлении также был указан список книг на этой полке?
  • 18 апреля 2024 г. 19:40
Ответы на вопрос 2
1. Рекурсию следует использовать, когда задачу можно естественным образом разбить на более мелкие подзадачи того же типа. Например, при обходе дерева структуры данных или при сложении чисел в последовательности Фибоначчи. В таких случаях рекурсия может упростить код и улучшить его читаемость.

Лучше обходиться без рекурсии, когда задача может быть эффективно решена без вызова функций внутри себя. Например, при простых итерациях по массиву данных или обработке циклических структур (таких как связанные списки).

2. Для настройки сериализации в JSON для библиотеки книг, где каждая книга должна содержать ссылку на полку, на которой она находится, а также список книг на этой полке, можно использовать следующий подход:

- Создать классы для представления книги и полки в библиотеке.
- В классе книги добавить поле для хранения ссылки на полку, на которой она находится.
- В классе полки добавить поле для хранения списка книг, находящихся на этой полке.
- При сериализации каждой книги добавить ссылку на полку, на которой она находится, и список книг на этой полке.
- При сериализации каждой полки добавить список всех книг, находящихся на этой полке.

Примерно такой код мог бы выглядеть на Python с использованием библиотеки json:

```python
import json

class Book:
    def __init__(self, title, shelf):
        self.title = title
        self.shelf = shelf

class Shelf:
    def __init__(self, number):
        self.number = number
        self.books = []

shelf1 = Shelf(1)
shelf2 = Shelf(2)

book1 = Book('Book1', shelf1)
shelf1.books.append(book1)

shelf1_json = json.dumps(shelf1.__dict__, default=lambda obj: obj.__dict__, indent=4)
print(shelf1_json)

book1_json = json.dumps(book1.__dict__, default=lambda obj: obj.__dict__, indent=4)
print(book1_json)
```

Этот код создаст две полки (shelf1 и shelf2) и одну книгу (book1), добавит книгу на полку и сериализует объекты в JSON с учетом ссылок и списков книг на полках.
JSON не предназначен для структур данных с циклическими ссылками. Вообще-то ты должен был словить исключение в этом случае, а не рекурсию. Очень странно, что этого не произошло. 
Тут есть две возможности:
1. Задуматься
2. Посмотреть на параметр default в json.dump(). Это должна быть функция, которая принимает объект, и возвращает словарь. Ты можешь явно проверять, что объект - один из твоих датаклассов, и удалять из полученного словаря обратные ссылки. Аналогично, у json.load() есть object_hook, который позволяет задать свою логику превращения загруженных из JSON словарей в объекты. Но серьёзно, так ли нужны обратные ссылки?
Похожие вопросы