繁体   English   中英

将装饰器参数传递给内部 function

[英]Pass decorator argument to inner function

我正在继续学习 python。但是我有一些想法但面临实施问题。 我正在使用 selenium 并且每个元素的原因我都有多个案例,例如:

submit_btn = (By.XPATH, "//button[@type='submit']")
revert_btn = (By.XPATH, "//button[@class='revert']")

这让我很恼火,因为我总是复制 By.CSS_SELECTOR 或 xpath。我想制作一个装饰器,它采用默认设置为“css”的路径参数和 by_what 参数,并用于操作 WebDriver,如:

@by("[data-qa='selected']")
def save_form(self):
   self.find_element().click()

我的方法 find_element 看起来像:

 def find_element(self, locator, time=10):
        try:
            el = WebDriverWait(self.browser, time).until(ec.presence_of_element_located(locator),
                                                         message=f"Can't find elements by locator {locator}")
            return el
        except TimeoutException:
            return False
        except StaleElementReferenceException:
            return WebDriverWait(self.browser, time).until(ec.staleness_of(locator),
                                                           message=f"Can't find element by locator {locator}")

或者也许是另一种方式。 我试图创建像这样的装饰器:

def by(selector, what="css", data_qa=True):
    def inner_function(function):
        def wrapper(param):
            if what == "css":
                find_by = By.CSS_SELECTOR
            elif what == "xpath":
                find_by = By.XPATH
            if data_qa:
                path = (find_by, f"[data-qa='{param}']")
            else:
                path = (find_by, selector)
            return function(path)

        return wrapper

    return inner_function

并且很高兴将其用作

@by('selected')
def get_selected_el(self)
   # set path returned by decorator to find element method
   self.find_element(smth_returned_by_decorator)

所以我想将定位器作为装饰器实现传递。 如何做呢?

执行类似操作的一种可能方法是在装饰器返回的 function 中没有公开的装饰器 function 中有一个参数:

# Decorator that automatically forwards an argument
def autoparam(param):
    def decorator(f):
        def wrapper(self):
            f(self, param)
        return wrapper
    return decorator

class MyClass:
    def method1(self, param):
        print(param)
    @autoparam('method2 value')
    def method2(self, param):
        self.method1(param)

# Test
obj = MyClass()
# Calling method2 does not require an argument
obj.method2()
# method2 value

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM