Как в классе ошибки обратиться к переменной другого класса?

Допустим, у нас есть такой код:

class Example(object):

    def __init__(self, arg):
        self.arg = arg

    class MyError(Exception):
        def __init__(self, errorin):
            self.errorin = errorin

        def __str__(self):
            return "Error in %s" % self.errorin
            sys.exit()

    def plus(self, num):
        try:
            return self.arg + num
        except:
            raise self.MyError(what_to_write_here) from None
            sys.exit()

Достаточно написать что-то на месте what_to_write_here или надо переделывать весь код?


Ответы (1 шт):

Автор решения: CrazyElf
x = Example(1)
x.plus("2")

Как сделать так, чтобы в ошибке MyError, которая будет вызывается из-за TypeError, было написано "Error in x"?

Дело в том, что x - это не сам объект Example(1), это ссылка на него. Причём, можно сделать множество ссылок на один объект:

x = y = z = Example(1)

В данном случае три переменных хранят ссылку на один объект Example(1).

Вы в принципе можете через globals() поискать объекты, у которых id совпадает c id(self) в вашем методе plus. Но проблема в том, что все эти объекты будут указывать на один и тот же объект Example.

Более того. Когда вы делаете x.plus, то вы вызываете метод plus не от переменной x, а от объекта Example, на который ссылается x. Т.е. Питон сначала получает из переменной x ссылку на объект Example, и дальше уже от этого объекта Example вызывает plus. В этот момент информация про то, что мы начали эту операцию с переменной x уже потеряна, вы её никак не можете восстановить на объектном уровне.

Всё, что у вас есть про x - это либо вы можете через globals() собрать все переменные, которые указывают на ваш объект (но между собой вы их не сможете различить):

            objs = ','.join(k for k,v in globals().items() if id(v) == id(self))
            raise self.MyError(objs) from None
...
x = y = z = Example(1)
x.plus("2")

# MyError: Error in x,y,z

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

P.S. Если вам нужно различать всё-таки не переменные x и т.п., а экземпляры класса Example между собой, то как вам уже посоветовали в комментариях - сделайте для этого какое-то отдельное поле в классе Example, заполняйте его в __init__ и оно будет вам доступно потом через self, как и все остальные поля экземпляра класса.

→ Ссылка