Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/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
Python 是否可以让contextlib.closing()调用任意清理方法而不是.close()呢_Python_With Statement - Fatal编程技术网

Python 是否可以让contextlib.closing()调用任意清理方法而不是.close()呢

Python 是否可以让contextlib.closing()调用任意清理方法而不是.close()呢,python,with-statement,Python,With Statement,我在python中使用with statement()自动管理上下文后的资源清理时遇到了一些问题。特别是,with语句始终假定资源清理方法为.close()。也就是说,在下面的代码块中,browser.close()在执行超出上下文时自动被调用,但是,browser.close()不是正确的清理,因为它只关闭当前窗口,而不是整个浏览器。它应该做的是调用browser.quit() 不幸的是,contextlib.closing没有提供一种自定义要调用的清理方法名称的方法,显然可以看到: 但是,我

我在python中使用
with statement
()自动管理上下文后的资源清理时遇到了一些问题。特别是,
with语句
始终假定资源清理方法为
.close()
。也就是说,在下面的代码块中,
browser.close()
在执行超出上下文时自动被调用,但是,
browser.close()
不是正确的清理,因为它只关闭当前窗口,而不是整个浏览器。它应该做的是调用
browser.quit()

不幸的是,
contextlib.closing
没有提供一种自定义要调用的清理方法名称的方法,显然可以看到:

但是,我注意到有一个参数
exec\u info
,但没有在该特定方法中使用。有人知道为什么吗


更大的问题是,正如标题所建议的,如果可能的话,如何让self.thing调用任意清理方法?如果不是,最好的解决办法是什么?我是否应该退回到使用
try…finally

好吧,这是python,您可以基于
contextlib创建自己的
closing
类。closing
并覆盖
\uuuuuuuuu退出()
方法:

import contextlib
from selenium import webdriver

class closing(contextlib.closing):
    def __exit__(self, *exc_info):
        self.thing.quit()


with closing(webdriver.Firefox()) as browser:
    browser.get('http://stackoverflow.com')

仅供参考,有人提议将
webdriver
设置为上下文管理器,但由于
无法修复
,因此关闭了它,因为
quit()
是关闭浏览器的正确方法,应该显式调用它,请参见。

除了alecxe的答案非常有效外,您还可以执行以下操作:

webdriver.Firefox.close = webdriver.Firefox.quit
现在存在
close
方法,该方法与
quit
方法相同

或者更好:

from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver
RemoteWebDriver.close = lambda self: self.quit()
这将修补基类以添加一个调用当前实例的
quit()
close()
方法,因此它将与所有驱动程序一起工作。(第一个只是修补Firefox驱动程序。)
lambda
是必需的,因为基类上的
quit()
方法在许多(所有?)驱动程序上被重写,因此在基类上指向
close
将调用基类的方法,而不是实际使用的类上的方法

无论哪种方式,该类现在都非常适合与
closing()
with
语句一起使用

webdriver.Firefox.close = webdriver.Firefox.quit
from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver
RemoteWebDriver.close = lambda self: self.quit()