#### 1. Implicit Int Поймите, что класс это тоже объект: ```python class A: pass print(id(A)) # 140199780173328 print(dir(A)) # ... ``` Декораторы также могут быть применены к классу. Как и в случае с функциями декоратор должен возвращать новый (или такой же) класс: ```python def replace_repr(cls): cls.__repr__ = lambda self: f"object of cls {cls.__name__}" return cls @replace_repr class A: pass print(A()) # object of cls A ``` Напишите декоратор `implicit_int`. Если приписать его к классу, то при обращении к необъявленному полю экземпляра этого класса будет возвращаться значение 0, Вам поможет магически метод [`__getattr__`](https://rszalski.github.io/magicmethods/#access). ```python @implicit_int class A: pass a = A() print(a.e + 589) # Вывод: 589 ``` #### 2. Timer Напишите [менеджер контекста](https://rszalski.github.io/magicmethods/#context), который позволит засекать время выполнения блока кода с помощью конструкции `with` и выводить это время на экран по выходу из блока. Пример использования: ```python with Timer(): do_some_long_stuff() ``` #### 3. Logger Напишите класс, которой ведет журнал, какие методы у него вызывались. То есть у объектов данного класса должна быть возможность вызвать любой метод с любыми аргументами, а потом можно вызвать специальный метод (удобно здесь использовать `__str__`), который выдаст строку-лог со всей информацией о вызовах и аргументах. Кроме того, должна быть возможность унаследоваться от данного класса, чтобы добавить логирование к любому классу. При этом функции, определенные в классе-наследнике, все равно должны выполняться. Для простоты игнорируйте атрибуты методов (докстринги и т.п.)