有没有办法重构这个 try/ except 块以避免 DRY 违规?

问题描述 投票:0回答:1

这是使用 Selenium 和 Python 构建 Web 自动化脚本的更大函数的一部分。该网站有时会提供弹出窗口,这会导致

ElementClickInterceptedException
,但弹出窗口并不总是提供;有时没有弹出窗口。

我编写了这个函数来关闭弹出窗口(如果它已提供):

def close_popup():
    try:
        WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.XPATH, '//x-button'))).click()
        time.sleep(1)
    except:
        NoSuchElementException
        print("No pop-up found")

然后我在主部分编写了一个 try/ except 块来调用该函数:

try:
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.LINK_TEXT, "Click here!"))).click()
except ElementClickInterceptedException:
    close_popup()
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.LINK_TEXT, "Click here!"))).click()

这确实按预期工作,但它违反了 DRY(不要重复自己),因为

try:
之后的行与块的最后一行相同。

我确实先搜索了这个,但没有找到与我的问题完全相同的。我发现那些人询问代码中的一些错误。我的代码确实有效,只是违反了 DRY。

我如何重构才能使我的代码符合 Python 风格并且不违反 DRY?

python refactoring repeat dry try-except
1个回答
0
投票

DRY 主要涉及将业务逻辑保留在一个地方;即不要到处重复逻辑决策,就像这样:

if len(user.subaccounts) > 3 and user.license == 'basic':
    raise UpgradeSubscription

应该在一个地方检查此类事情,而不是在整个代码库中的多个地方。因为当您的业务规则最终不可避免地发生变化时,这将导致不一致。

所以,这里并没有特别违反DRY;您的两行代码非常接近,如果更改其中一行,将其复制粘贴到下面三行可能不会有什么问题。

话虽如此,明显的选择是:

def close():
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.LINK_TEXT, "Click here!"))).click()

try:
    close()
except ElementClickInterceptedException:
    close_popup()
    close()

或者类似的东西:

for i in range(2):
    try:
        WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.LINK_TEXT, "Click here!"))).click()
    except ElementClickInterceptedException:
        if i == 0:
            close_popup()
        else:
            raise

虽然前一个可以说更具可读性。

© www.soinside.com 2019 - 2024. All rights reserved.