Как в классе ошибки обратиться к переменной другого класса?
Допустим, у нас есть такой код:
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 шт):
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, как и все остальные поля экземпляра класса.