【问题标题】:Python "with" statement: __exit__() ignoredPython "with" 语句:__exit__() 被忽略
【发布时间】:2016-07-18 03:03:48
【问题描述】:

考虑到这个小的 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

【问题讨论】:

  • 你应该从你的__enter__方法返回你想要分配给driver的值。
  • @PaulRooney 啊,是的,我在示例中忘记了这一点,但这不是真正的问题!真正的代码已经有了!

标签: python python-3.x selenium selenium-webdriver


【解决方案1】:

请注意,回溯显示您仍在 WebDriver 对象的 __init__() 中 - 换句话说,with 语句尚未执行,Python 仍在评估其参数。我不确定确切的规则,但我很确定如果 __enter__() 还没有被调用,__exit__() 将永远不会被调用。

【讨论】:

  • 或者如果__enter__ 没有完成:get 期间的中断也不会启动with
猜你喜欢
  • 2015-08-13
  • 2018-03-26
  • 1970-01-01
  • 2018-04-19
  • 2017-09-22
  • 2014-03-04
  • 2016-02-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多