Скажи как работает динамическое создание класса через type

15. Скажи как работает динамическое создание класса через type

Условие задачи Не запуская код, определите, что будет выведено в каждом случае при использовании type для динамического создания класса и его экземпляра.

print(type("A", (object,), {"a": 1, "b": 2})) >>
print(type("A", (object,), {"a": 1, "b": 2})()) >>
Спойлеры к решению
Подсказки
  • type(name, bases, attrs) динамически создаёт новый класс.
  • Первый аргумент "A" — имя создаваемого класса.
  • Второй аргумент (object,) — кортеж родительских классов.
  • Третий аргумент {"a": 1, "b": 2} — атрибуты класса.
  • Первый print() выводит сам класс.
  • Второй print() создаёт экземпляр этого класса и выводит объект.
  • Так как у класса нет __str__ или __repr__, экземпляр выводится в стандартном виде.
Решение
print(type("A", (object,), {"a": 1, "b": 2}))
print(type("A", (object,), {"a": 1, "b": 2})())

Результат будет примерно таким:

<class '__main__.A'>
<__main__.A object at 0x000001F3A2B4C700>

Первый вызов:

type("A", (object,), {"a": 1, "b": 2})

создаёт новый класс с именем A, поэтому при выводе получаем:

<class '__main__.A'>

Второй вызов:

type("A", (object,), {"a": 1, "b": 2})()

сначала создаёт класс A, а затем сразу создаёт его экземпляр. Так как в классе не определены методы __str__ и __repr__, Python выводит объект в стандартном формате:

<__main__.A object at 0x...>

Адрес в памяти после 0x каждый раз может быть другим.