2025, Nov 24 06:01

Исправляем вывод объекта в Python: __str__ вместо __string__

Разбор ошибки в Python: вместо сетки 6×6 объект печатается как module.Class object. Почему нужен метод __str__ (а не __string__) и как быстро исправить код.

Когда при выводе экземпляра класса в Python вы видите <module.Class object at 0x...> вместо аккуратно отформатированной строки, чаще всего виноват специальный метод, который так и не был вызван. В этом кратком разборе рассмотрим ситуацию, где логика форматирования выглядит верной, тесты есть, но одно-единственное имя метода ломает весь механизм.

Проблема

Класс строит сетку 6×6 и должен возвращать пригодное для печати представление с разделителем после третьего столбца и третьей строки. Логика корректна, но вывод экземпляра показывает лишь стандартное представление объекта, а не задуманный вид сетки.

Пример кода с проблемой

import numpy as npx
class Grid:
    CELL_NONE = 0
    def __init__(self):
        self.flat = npx.array([Grid.CELL_NONE] * 36)
        self.matrix = npx.reshape(self.flat, (6, 6))
    def __string__(self):
        out = ""
        for r in range(6):
            for c in range(6):
                out += f"{str(self.matrix[r, c])} "
                if c == 2:
                    out += "| "
            out += "\n"
            if r == 2:
                out += "------+------\n"
        return out
obj = Grid()
print(obj)

Ожидался аккуратный вывод сетки:

0 0 0 | 0 0 0
0 0 0 | 0 0 0
0 0 0 | 0 0 0
------+------
0 0 0 | 0 0 0
0 0 0 | 0 0 0
0 0 0 | 0 0 0

Что происходит

Функция форматирования названа __string__, однако при вызове print для объекта Python ищет метод с именем __str__. Из‑за неправильного имени специальный метод не вызывается, и вместо него печатается стандартное представление объекта.

Исправление и корректный код

Переименуйте метод в __str__, чтобы Python знал, что вызывать при печати экземпляра. Остальную логику можно оставить без изменений.

import numpy as npx
class Grid:
    CELL_NONE = 0
    def __init__(self):
        self.flat = npx.array([Grid.CELL_NONE] * 36)
        self.matrix = npx.reshape(self.flat, (6, 6))
    def __str__(self):
        out = ""
        for r in range(6):
            for c in range(6):
                out += f"{str(self.matrix[r, c])} "
                if c == 2:
                    out += "| "
            out += "\n"
            if r == 2:
                out += "------+------\n"
        return out
obj = Grid()
print(obj)

Теперь при печати экземпляра вы получите нужную раскладку 6×6 с разделителем ровно там, где задумано.

Почему это важно

Специальные методы в Python — это строгие точки входа. Малейшая опечатка в их именах незаметно обходит вашу логику и уводит от истинной причины. В нашем примере функция форматирования была и работала, но среда выполнения её просто не вызывала.

Вывод и практические советы

Настраивая вывод объекта, реализуйте метод __str__ с точным именем. Если видите строку с объектом в угловых скобках, предположите, что специальный метод не сработал, и сначала проверьте написание. Небольшие прицельные проверки — например, вывод экземпляра сразу после создания — помогают рано отлавливать такие ошибки и сокращают цикл отладки.