Bac*_*sau 4 python python-3.x python-3.6
我所处的情况是类__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()
Run Code Online (Sandbox Code Playgroud)
但是,最后一行不起作用,因为that_thing未定义。奇怪的是,我可以发誓我以前做过类似的事情而且效果很好。我什至想过如何阻止人们使用这样一个未完成的实例,因为我发现即使出现错误它也会被创建。现在我想用它,但它不起作用。嗯...?!?
PS:something是我自己写的,所以我可以控制一切。
您可以通过调用object.__new__()创建对象来完成此操作。然后调用__init__()创建对象。
这将执行所有可能的代码。
class IrrelevantException(Exception):
"""This is not important, keep executing."""
pass
class something(object):
def __init__(self):
print("Doing important stuff.")
raise IrrelevantException()
def do_something_useful(self):
print("Now this is useful.")
that_thing = object.__new__(something) # Create the object, does not call __init__
try:
that_thing.__init__() # Now run __init__
except IrrelevantException:
print("Something less important failed.")
that_thing.do_something_useful() # And everything that __init__ could do is done.
Run Code Online (Sandbox Code Playgroud)
编辑,正如@abarnert 指出的。此代码确实假定已__init__()定义,但__new__()实际上并未定义。
现在如果可以假设__new__()不会出错,就可以object.__new__()在代码中替换。
但是,如果 中存在错误object.__new__(),则无法创建实例并__new__()对其应用 中的操作。
这是因为__new__()返回实例,而不是__init__()操纵实例。(当您调用 时something(),默认__new__()函数实际上会调用__init__(),然后悄悄返回实例。)
所以这段代码最健壮的版本是:
class IrrelevantException(Exception):
"""This is not important, keep executing."""
pass
class something(object):
def __init__(self):
print("Doing important stuff.")
raise IrrelevantException()
def do_something_useful(self):
print("Now this is useful.")
try:
that_thing = something.__new__(something) # Create the object, does not call __init__
except IrrelevantException:
# Well, just create the object without calling cls.__new__()
that_thing = object.__new__(something)
try:
that_thing.__init__() # Now run __init__
except IrrelevantException:
print("Something less important failed.")
that_thing.do_something_useful()
Run Code Online (Sandbox Code Playgroud)
因此,同时这两个都回答了问题,后一个也应该在__new__()出现错误的(诚然罕见)情况下有所帮助,但这并不会停止do_something_useful()工作。