如果在python中需要减少多个else

问题描述 投票:3回答:2

我正在尝试使用python使用selenium-webdriver自动化基本html网站的回归测试。我编写了一个函数,它将从excel中获取输入,以确定网页上元素的定位符类型,如下所示:

            if locator_type == "ID":
                web_element = self.__driver.find_element_by_id(element)
            elif locator_type == "NAME":
                web_element = self.__driver.find_element_by_name(element)
            elif locator_type == "XPATH":
                web_element = self.__driver.find_element_by_xpath(element)
            elif locator_type == "TAG_NAME":
                web_element = self.__driver.find_element_by_tag_name(element)
            elif locator_type == "LINK_TEXT":
                web_element = self.__driver.find_element_by_link_text(element)
            elif locator_type == "CLASS_NAME":
                web_element = self.__driver.find_element_by_class_name(element)
            elif locator_type == "PARTIAL_LINK_TEXT":
                web_element = self.__driver.find_element_by_partial_link_text(element)

这样我们就可以指定定位器类型并给出实际定位器('element'),以便selenium可以尝试在web页面上找到web元素。有没有办法减少elif语句或任何其他更好的方式来编写这个部分?

Too many if statements

我在上面的链接中尝试了这个方法,但它没有帮助我。请帮我解决这个问题。

编辑我尝试创建这样的字典

locator_dict = {
'ID' : driver.find_element_by_id(element),
'NAME' : driver.find_element_by_name(element)}

然后我收到一个错误,说明元素没有定义

python python-3.x selenium-webdriver
2个回答
4
投票

您可以构造要从locator_type调用的函数的名称,然后调用它:

locator_type_lower = locator_type.lower()

find_function_name = 'find_element_by_{}'.format(locator_type_lower)

driver_function_to_call = getattr(self.__driver, find_function_name)

web_element = driver_function_to_call(element)

您应该将其包装在一些错误检查中 - 检查函数是否存在,检查它是否可调用等。

这样做:将locator_type转换为小写,然后构建希望自我.__驱动程序中现有函数的函数名称,然后使用您的元素调用它。

这种方法的优点是你不必将字符串映射到函数 - 如果self.__driver有一个名为find_element_by_foo_bar_length的函数,那么你可以简单地将FOO_BAR_LENGTH添加到excel电子表格中,它将被调用,无需更新你的映射字典。

编辑:更新评论

要将locator_type字符串转换为By类的属性:

locator_type = 'ID'
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((getattr(By, locator_type), element)))

10
投票

各个子句的主体之间的唯一区别是你实际调用的方法。你可以将其分解为dict

d = {
    "ID": self.__driver.find_element_by_id,
    "NAME": self.__driver.find_element_by_name,
    # etc
}

if locator_type in d:
    web_element = d[locator_type](element)
else:
    # do something if you haven't defined a method for locator_type

你也可以使用methodcaller,虽然这第一次尝试使d依赖于element

from operator import methodcaller

methods = [
    ("ID", "find_element_by_id"),
    ("NAME", "find_element_by_name"),
    # etc
]
d = { tag: methodcaller(method, element) for tag, method in methods } 

if locator_type in d:
    web_element = d[locator_type](self.__driver)

要完全独立于驱动程序或元素,请使用

d = dict(methods)
if locator_type in d:
    web_element = methodcaller(d[locator_type], element)(self.__driver)
© www.soinside.com 2019 - 2024. All rights reserved.