我遇到类__init__方法的一些微不足道的重要部分可能引发异常的情况.在这种情况下,我想显示错误消息,但继续使用实例.
一个非常基本的例子:
class something(object):
def __init__(self):
do_something_important()
raise IrrelevantException()
def do_something_useful(self):
pass
try:
that_thing = something()
except IrrelevantException:
print("Something less important failed.")
that_thing.do_something_useful()
但是,最后一行不起作用,因为没有定义that_thing.奇怪的是,我可以发誓我以前做过这样的事情并且工作正常.我甚至想知道如何阻止人们使用这样一个未完成的实例,因为我发现即使出现错误也会创建它.现在我想使用它,它不起作用.嗯…?!?
PS:我自己写的东西,所以我控制着一切.
最佳答案 来自评论:
PS: something was written by myself, so I’m in control of everything.
那么,答案是显而易见的:只需删除那个引发IrrelevantException()
当然,您的真实代码可能没有引发IrrelevantException,而是调用可能引发的某些dangerous_function().但那没关系;你可以像在其他任何地方一样处理异常;你在__init__方法中的事实没有区别:
class something(object):
def __init__(self):
do_something_important()
try:
do_something_dangerous()
except IrrelevantException as e:
print(f'do_something_dangerous raised {e!r}')
do_other_stuff_if_you_have_any()
这里的所有都是它的.你的__init__没有理由提出异常,因此首先不会出现如何处理异常的问题.
如果您无法修改某些内容,但可以将其子类化,那么您不需要任何花哨的东西:
class IrrelevantException(Exception):
pass
def do_something_important():
pass
class something(object):
def __init__(self):
do_something_important()
raise IrrelevantException()
def do_something_useful(self):
pass
class betterthing(something):
def __init__(self):
try:
super().__init__() # use 2.x style if you're on 2.x of course
except IrrelevantException:
pass # or log it, or whatever
# You can even do extra stuff after the exception
that_thing = betterthing()
that_thing.do_something_useful()
现在do_something_important被调用,并且一个实例得到了我能够保存并且调用do_something_useful的返回,依此类推.正是你在寻找什么.
你当然可以用一些聪明的重命名技巧来隐藏一些东西:
_something = something
class something(_something):
# same code as above
…或者只是使用包装器函数monkeypatch something .__ init__而不是包装类:
_init = something.__init__
def __init__(self):
try:
_init(self)
except IrrelevantException:
pass
something.__init__ = __init__
但是,除非有一个很好的理由让你无法明确表示你正在添加一个包装器,否则最好是明确的.