考虑到这个小Python类,每当我使用 Ctrl + C 停止脚本时,__exit__
函数在引发异常之前运行:
import time
class MyClass(object):
def __init__(self):
pass
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
print('------ cleanup ------')
with MyClass():
time.sleep(100)
运行:
$ python3 test.py
^C------ cleanup ------
Traceback (most recent call last):
File "test.py", line 15, in <module>
time.sleep(100)
KeyboardInterrupt
在类似的Chrome WebDriver子类代码中,为什么忽略我的清理功能?
import selenium
from selenium.webdriver.common.by import By
class WebDriver(selenium.webdriver.Chrome):
def __init__(self, url, *args, **kwargs):
super().__init__(*args, **kwargs)
self.url = url
def __enter__(self):
self.get(self.url)
return self
def __exit__(self, exc_type, exc_value, traceback):
print('------ cleanup ------')
with WebDriver('https://google.com') as driver:
driver.find_element(By.ID, 'lst-ib').send_keys('Search')
运行:
$ python3 test2.py
^CTraceback (most recent call last):
File "test2.py", line 19, in <module>
with WebDriver('https://google.com') as driver:
File "test2.py", line 9, in __init__
super().__init__(*args, **kwargs)
File "/vagrant/app/lib/python3.5/site-packages/selenium/webdriver/chrome/webdriver.py", line 62, in __init__
self.service.start()
File "/vagrant/app/lib/python3.5/site-packages/selenium/webdriver/common/service.py", line 90, in start
time.sleep(1)
KeyboardInterrupt
使用try: ... finally:
语句强制它可以正常工作:
try:
with WebDriver('https://google.com') as driver:
driver.find_element(By.ID, 'lst-ib').send_keys('Search')
finally:
print('------ cleanup ------')
运行:
^C------ cleanup ------
Traceback (most recent call last):
File "test2.py", line 20, in <module>
with WebDriver('https://google.com') as driver:
File "test2.py", line 9, in __init__
super().__init__(*args, **kwargs)
File "/vagrant/app/lib/python3.5/site-packages/selenium/webdriver/chrome/webdriver.py", line 62, in __init__
self.service.start()
File "/vagrant/app/lib/python3.5/site-packages/selenium/webdriver/common/service.py", line 90, in start
time.sleep(1)
KeyboardInterrupt
答案 0 :(得分:5)
请注意,回溯显示您仍然在WebDriver对象的__init __()中 - 换句话说, with 语句尚未执行,Python仍在评估其参数。我不确定具体的规则,但我很确定如果尚未调用__enter __(),__exit __()将永远不会被调用。