如果使用python,则需要减少多个else

如果使用python,则需要减少多个else,python,python-3.x,selenium-webdriver,Python,Python 3.x,Selenium Webdriver,我正在尝试使用SeleniumWebDriver和python自动化基本html网站的回归测试。我编写了一个函数,该函数将从excel中获取输入,以确定网页上元素的定位器类型,如下所示: if locator_type == "ID": web_element = self.__driver.find_element_by_id(element) elif locator_type == "NAME":

我正在尝试使用SeleniumWebDriver和python自动化基本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)
这样,我们就可以指定定位器类型并给出实际的定位器(“元素”),以便selenium可以尝试在web页面上查找web元素。有没有办法减少elif语句或其他更好的方法来编写本部分

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

编辑 我试着创造一个这样的口述

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

然后我收到一个错误,说元素未定义

您可以从
定位器类型
构造要调用的函数名,然后调用它:

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)
您可能应该将其包装在一些错误检查中—检查函数是否存在,检查它是否可调用,等等

它的作用是: 将定位器类型转换为小写,然后在self.\uu驱动程序中构建现有函数的函数名,然后使用元素调用它

这种方法的优点是,您不必将字符串映射到函数-如果
self.\uu驱动程序
有一个名为
find\u element\u by\u foo\u bar\u length
的函数,那么您只需将
foo\u bar\u length
添加到excel电子表格中,它就会被调用,无需更新映射命令

编辑:更新评论

要将定位器类型字符串转换为
By
类的属性,请执行以下操作:

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

不同子句主体之间的唯一区别是实际调用的方法。您可以将其分解为一个
命令

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
依赖于
元素

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)

你能详细说明为什么你链接的答案对你没有帮助吗?dict似乎可以大大减轻示例代码中的多个
if
elif
块。你是不是很难弄清楚如何散列函数调用?也就是说,如何在散列中存储函数。@MikeHolt我不明白散列函数调用有什么帮助?请给我一些见解。对不起,我的措辞有点马虎。我指的是将函数作为值存储在散列中(在Python中称为dict),正如chepner的回答所示。非常感谢您澄清这一点,我会尝试一下并向您更新。这很有效,但有一个小问题。。在调用字典之前需要实例化驱动程序对象?如图所示,是的。我将使用
methodcaller
添加一个解决方案,我省略了它,因为它看起来有点复杂,但使
d
独立于驱动程序。切普纳,你能再次提供帮助吗?如何在selenium中为显式等待函数生成方法调用方。示例:“WebDriverWait(driver,10).until(EC.presence\u of_element\u located((By.ID,“myDynamicElement”)))””嘿,Danielle,我们有没有办法为下面的语句实现这一点?“WebDriverWait(driver,10)。直到(EC.presence\u元素位于((By.ID,“myDynamicElement”))))””。我尝试了以下方法:
driver.get('https://www.google.com/“)locator_type='NAME'element='q'exp_wait_str=“WebDriverWait({},10)。直到(EC.presence_of_element_located((By.{},{}))”。format(driver,locator_type,element)fun=getattr(driver,exp_wait_str)web_element=fun(locator_type,element)
我试图理解这个概念,但无法使用您为上述陈述建议的方法。请调查一下,你好!您试图做的是动态地从By类中提取locator_类型。我将更新上面的答案,告诉你如何做到这一点。非常感谢Danielle,它起到了很好的作用,你帮助删除了30多行重复代码。