✅ Решения заданий

⚠️ Рекомендация: попробуйте решить задания самостоятельно, прежде чем смотреть ответы. Решения — это последняя инстанция, когда собственные попытки исчерпаны.

⚡ Кратко

  • Задание 1: верны a и d.
  • Задание 2: верны b и e.
  • Задание 3: у статического метода не должно быть self.
  • Задание 4: City со __str__ и статическим методом distance.
  • Задание 5: @classmethod from_string для парсинга строки.

Решение 1. Утверждения об атрибутах класса

Правильный ответ: a, d.

  • a — верно: атрибут класса общий для всех объектов.
  • b — неверно: атрибуты класса создаются в теле класса, а не внутри __init__.
  • c — неверно: присваивание через объект создаёт атрибут объекта, не меняя класс.
  • d — верно: поле класса можно прочитать через объект, если у объекта нет собственного поля с таким именем.

Решение 2. Утверждения о @classmethod

Правильный ответ: b, e.

  • a — неверно: первый аргумент — cls, а не self.
  • b — верно: через cls(...) можно создать новый объект.
  • c — неверно: у классового метода нет доступа к полям конкретного объекта, если объект не передан явно.
  • d — неверно: классовый метод можно вызывать и через объект, и через класс.
  • e — верно: cls — это ссылка на сам класс.

Решение 3. Ошибка в статическом методе

Ошибка: статический метод не получает self. Если параметр self не нужен, его нужно убрать.

class Person:
    @staticmethod
    def greet() -> None:
        print("Hello!")


Person.greet()

Решение 4. Расстояние между городами

Метод distance возвращает кортеж разниц координат. В учебном материале он оформлен как статический, потому что не использует self.

class City:
    def __init__(self, name: str, latitude: float, longitude: float) -> None:
        self.name = name
        self.latitude = latitude
        self.longitude = longitude

    def __str__(self) -> str:
        return f"City: {self.name} ({self.latitude}, {self.longitude})"

    @staticmethod
    def distance(city1: "City", city2: "City") -> tuple[float, float]:
        lat_diff = round(city1.latitude - city2.latitude, 2)
        lon_diff = round(city1.longitude - city2.longitude, 2)
        return lat_diff, lon_diff


berlin = City("Berlin", 52.52, 13.40)
paris = City("Paris", 48.85, 2.35)

print(berlin)
print(paris)
print("Distance:", City.distance(berlin, paris))

Логика: координаты городов передаются через объекты. Разница округляется до двух знаков, чтобы вывод был аккуратным.

Решение 5. Создание объекта из строки

Для создания объекта из строки удобен классовый метод: он знает, какой класс нужно инстанцировать.

class City:
    def __init__(self, name: str, latitude: float, longitude: float) -> None:
        self.name = name
        self.latitude = latitude
        self.longitude = longitude

    def __str__(self) -> str:
        return f"City: {self.name} ({self.latitude}, {self.longitude})"

    @classmethod
    def from_string(cls, data: str) -> "City":
        name_part, coords_part = data.split(":")
        lat, lon = map(float, coords_part.split(","))
        return cls(name_part, lat, lon)

    @staticmethod
    def distance(city1: "City", city2: "City") -> tuple[float, float]:
        lat_diff = round(city1.latitude - city2.latitude, 2)
        lon_diff = round(city1.longitude - city2.longitude, 2)
        return lat_diff, lon_diff


rome = City.from_string("Rome:41.89,12.51")
print(rome)

Логика: строка разбивается по символу :, координаты — по запятой. Классовый метод возвращает cls(name, lat, lon), то есть новый объект текущего класса.

Проверить по документации: про @staticmethod и @classmethod см. Built-in Functions; про статический анализ типов — mypy.