在又一次可怕的错误搜索之后,我想知道以下内容: 是否可以向所有异常添加一些额外信息,例如对象的名称。 这将大大提高错误的可读性,并更快地查找错误(或输入错误)。如果一个人有许多来自同一个类的对象,因此共享很多代码,但具有不同的属性,情况尤其如此。在这种情况下,如果错误消息还指出错误中对象的名称,这将非常有用。
一个简单的例子:我正在尝试模拟不同类型的设施,一个养 pig 场和一个奶牛场。它们是同一个类,但具有不同的属性。在模拟中进行了许多设施,如果引发异常,如果将对象的名称添加到异常中将非常有帮助。
class facility():
def __init__(self, name):
self.name = name
self.animals = []
farms = []
farms.append(facility('cow_farm'))
farms.append(facility('pig_farm'))
print farms[0].stock
这会产生
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: facility instance has no attribute 'stock'
但我想添加设施的名称:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: facility instance has no attribute 'stock'
Name of object: cow_farm
我试过类似的东西
def print_name(exception):
try:
print self.name
except AttributeError:
pass
raise exception
@print_name
Exception
但这行不通。是否有可能做这样的事情,或者是否有充分的理由不这样做?
最佳答案
如果你想处理错误和添加信息,你可以这样做:
farm = farms[0]
try:
print farm.stock
except AttributeError:
raise AttributeError("{} has no attribute 'stock'".format(farm.name))
但是,在 __init__
中添加空的 stock
以避免此错误可能更明智。
你应该 never use a bare except
,因为它对您隐藏了有用的信息(特别是在开发和调试时!)通常,每个 try
block 应该尽可能短,最好只做一件事。如果多个错误可能源于单个 try
block ,您可以添加多个处理程序:
try:
print farm.stock["hay"]
except AttributeError:
raise AttributeError("{} has no attribute 'stock'".format(farm.name))
except KeyError:
raise KeyError("{} has no 'hay' in 'stock'".format(farm.name))
(尽管请注意,在 __init__
中添加 self.stock
并检查 if "hay"in farm.stock:
会让你免于此错误处理。)
如果发生您未预料到的错误,通常最好将该错误向上传播到调用堆栈,直到它被显式处理或您看到它。否则,您将走向这种愚蠢的反模式:
def some_func(*args, **kwargs):
try:
# all of some_func's content goes here
except:
raise Exception("Something went wrong in some_func().")
这对您毫无用处,而且对于任何试图使用您的代码的人来说都非常令人沮丧。
如果你想在类
级别处理这样的AttributeError
,你可以这样做:
class Facility(object):
def __init__(self, ...):
...
def __getattr__(self, key):
"""Called on attempt to access attribute instance.key."""
if key not in self.__dict__:
message = "{} instance '{}' has no attribute '{}'."
message = message.format(type(self).__name__,
self.name, key)
raise AttributeError(message)
else:
return self.__dict__[key]
然后你会得到
>>> farm = Facility("pig farm")
>>> print farm.stock
...
"AttributeError: Facility instance 'pig farm' has no attribute 'stock'."
如果你想在多个类中使用这个模式,你可以创建一个父类(super class):
class ProtectedAttrs(object):
def __init__(self, name):
self.name = name
def __getattr__(self, key):
...
class Facility(ProtectedAttrs):
def __init__(self, name):
super(Facility, self).__init__(name)
self.animals = []
这种方法适用于某些类型的错误。但是,我不知道有任何通用方法可以通过引用所涉及的实例来处理所有 错误。
关于python - 向所有 python 异常添加额外信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20881403/