在__init__ 中引发异常是完全可以的。然后,您将使用 try/except 包装对象启动/创建调用并对异常做出反应。
一个潜在的奇怪结果是 __del__ 无论如何都会运行:
class Demo(object):
def __init__(self, value):
self.value=value
if value==2:
raise ValueError
def __del__(self):
print '__del__', self.value
d=Demo(1) # successfully create an object here
d=22 # new int object labeled 'd'; old 'd' goes out of scope
# '__del__ 1' is printed once a new name is put on old 'd'
# since the object is deleted with no references
现在尝试使用我们正在测试的值2:
Demo(2)
Traceback (most recent call last):
File "Untitled 3.py", line 11, in <module>
Demo(2)
File "Untitled 3.py", line 5, in __init__
raise ValueError
ValueError
__del__ 2 # But note that `__del__` is still run.
创建值为2 的对象会引发ValueError 异常,并显示__del__ 仍在运行以清理对象。
请记住,如果您在__init__ 期间引发异常,您的对象将不会获得名称。 (但是,它将被创建和销毁。由于__del__ 与__new__ 配对,它仍然会被调用)
即,就像这样不会创建x:
>>> x=1/0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
潜行者:
>>> x='Old X'
>>> x=1/0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>> x
'Old X'
如果你发现 __init__ 的异常也是一样的:
try:
o=Demo(2)
except ValueError:
print o # name error -- 'o' never gets bound to the object...
# Worst still -- 'o' is its OLD value!
所以不要试图引用不完整的对象o——当你到达except时它已经超出了范围。 o 这个名字要么什么都没有(即,如果你尝试使用它,NameError)或者它的旧值。
如此结束(感谢 Steve Jessop 提出的User Defined Exception 想法),您可以包装对象的创建并捕获异常。只需弄清楚如何对您正在查看的操作系统错误做出适当的反应。
所以:
class ForbiddenTwoException(Exception):
pass
class Demo(object):
def __init__(self, value):
self.value=value
print 'trying to create with val:', value
if value==2:
raise ForbiddenTwoException
def __del__(self):
print '__del__', self.value
try:
o=Demo(2)
except ForbiddenTwoException:
print 'Doh! Cant create Demo with a "2"! Forbidden!!!'
# with your example - react to being unusable to create a directory...
打印:
trying to create with val: 2
Doh! Cant create Demo with a "2"! Forbidden!!!
__del__ 2