Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在初始化时调用异常时的退出方法?_Python_Python 2.7 - Fatal编程技术网

Python 如何在初始化时调用异常时的退出方法?

Python 如何在初始化时调用异常时的退出方法?,python,python-2.7,Python,Python 2.7,假设您有一个定义了\uuuuuuuuuuuuuuuuuuuuuuuuuuuuu和\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu class MyClass: def f(self): raise Exception def __enter__(self): return self def __exit__(self, type, value, traceback): pas

假设您有一个定义了
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuu
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

class MyClass:
    def f(self):
        raise Exception
    def __enter__(self): 
        return self
    def __exit__(self, type, value, traceback):
        pass
如果在
with
块中引发异常,如下所示:

with MyClass() as ins:
    ins.f()
将隐式调用
\uuuuuuuuuuuuu退出\uuuuuu
方法,这非常好

但是,如果您的班级是这样的:

class MyClass:
    def __init__(self):
        self.f()
    def f(self):
        raise Exception
    def __enter__(self): 
        return self
    def __exit__(self, type, value, traceback):
        pass
您可以这样实例化它:

with MyClass() as ins:
    pass

当在
\uuuu init\uuuu
方法中引发异常时,
\uuuuu enter\uuuuu
尚未被调用,
\uuuu exit\uuuuu
也未被调用,这不是很好。解决此问题的最佳方法是什么?

显然,您不能使用无法作为上下文管理器启动的类,因此必须先创建实例,然后才能在with块中使用它

例如:

try:
    ins = MyClass()
except Exception as e: 
    print "Cant initiate MyClass"
else:
    with ins:
        pass
您可以通过将额外资源传递给类而不是在初始化期间创建它们来添加额外资源:

with spawnResource() as res, MyClass(res) as y:
    print x,y

正如其他人指出的,没有干净的方法,因为你试图做的事情很尴尬

简单的方法是:

如果您想在
\uuuu exit\uuuu
中清理某些内容,请在中初始化它
\uuuu输入

例如


除了在
\uuuu init\uuuu()
中捕获异常之外,我很好奇在调用对象的
\uuuu enter\uuuuu
后引发异常时,我是否能够获得良好的隐式捕获,希望能够避免额外的
try
块。也许在
\uuuuu init\uuuuu
中捕获异常是一种可行的方法,只是想知道是否有更具Python风格的方法可以避免我必须从本质上复制
\uuuuuuuu退出\uuuuuu
方法Python无法在这里调用
\uuuuuuuu退出\uuu
方法;这是一种针对实例的方法,该实例从未有机会完成构建。没有实例,没有退出方法。您唯一的办法是自己处理
。\uuuu init\uuuu()
中的异常,以确保实例构造完成。当然可以,但是假设在初始化过程中发生了一些事情,如果初始化不成功,我想清理这些事情。对象打开一些文件句柄或其他东西。有没有办法在初始化失败时隐式调用方法?我可以直接调用
\uuuuu exit\uuuuu
,但这对于我来说似乎有点笨拙,我需要切换代码的逻辑,首先生成资源,然后将它们传递给类。这样你就可以再次使用
了。啊,对了,这听起来确实是一个更好的方法
class MyClass:
    def f(self):
        raise Exception
    def __enter__(self):
        print 'in __enter__'
        # acquire it here...
        return self
    def __exit__(self, type, value, traceback):
        print 'in __exit__'
        # release it here...

with MyClass() as ins:
    print 'calling f()'
    ins.f()