在子类中调用抽象基类方法时位置参数错误过多

Posted

技术标签:

【中文标题】在子类中调用抽象基类方法时位置参数错误过多【英文标题】:Too much positional argument error when calling abstract base class method in child class 【发布时间】:2022-01-14 22:59:10 【问题描述】:

我有以下代码:

from abc import ABC

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from webdriver_manager.chrome import ChromeDriverManager


def xpath():
    return By.XPATH, '//*'


class BasePage(ABC):
    def __init__(self, driver):
        self._driver = driver
        self._driver.implicitly_wait(10)
        self._wait = WebDriverWait(driver, 10)

    def wait_for_page_to_load(self):
        self._wait.until(self._is_page_ready)

    def click_something(self):
        self._driver.find_element(*xpath()).click()
        self.wait_for_page_to_load()

    def _is_page_ready(self):
        state = self._driver.execute_script("return document.readyState;")
        return state == "complete"


class ChildPage(BasePage):
    def __init__(self, driver):
        super().__init__(driver)


c = ChildPage(webdriver.Chrome(ChromeDriverManager().install()))
c._driver.get("http://google.com")
c.click_something()

导致错误:

TypeError: _is_page_ready() 接受 1 个位置参数,但给出了 2 个

任何线索为什么它不起作用?解决方法是将 _is_page_ready 设为静态,但这种语法看起来并不错误,所以我很好奇它为什么会抛出这个错误。

【问题讨论】:

这与 ABC 或继承无关,您只是将带有错误签名的回调函数(绑定方法 self._is_page_ready)传递给 self._wait.until。它想要传递一个论点,但你不期望它。阅读库文档以了解该参数是什么。 Selenium Webdriver 是哪一个库文档?我读了它,我没有发现任何相关内容。 给出的示例here(在自定义等待条件下)表明驱动程序被传递给回调(它建议应该是一个可调用的类,但这似乎没有必要)。尝试在_is_page_ready 中添加一个额外的参数(可以忽略),看看是否有帮助? 你说得对,类似这样的工作:def _is_page_ready(self, x): 我在调试中看到 x 是一个 WebDriver。但是为什么 WebDriverWait 对象将 WebDriver 对象传递给 _is_page_ready 函数?我不确定代码中的定义是什么 【参考方案1】:

此错误消息...

TypeError: _is_page_ready() takes 1 positional argument but 2 were given

...暗示_is_page_ready() 被定义为采用一个位置参数:

def click_something(self):

其中,在您还尝试访问 driver 的方法中:

state = self._driver.execute_script("return document.readyState;")

您还需要将 driver 作为参数传递:

def _is_page_ready(self, driver):
    state = self._driver.execute_script("return document.readyState;")
    return state == "complete" 

【讨论】:

感谢@DebanjanB,这是正确的,我正在尝试访问驱动程序,但我正在从现有对象(self)获取驱动程序并且不想将其他驱动程序作为参数传递。所以这里唯一的解决办法就是把签名改成(self, driver)不使用? 好的,我意识到等待中的直到方法正在将驱动程序传递给我们传递给直到的方法。它在 WebDriverWait 类中可见。

以上是关于在子类中调用抽象基类方法时位置参数错误过多的主要内容,如果未能解决你的问题,请参考以下文章

基类和子类函数名相同且参数类型一样,基类函数如何被覆盖,还存在吗?存在何处?请详细回答,谢谢~~~~

在c#中将基类动态转换为子类

如何将子类作为期望基类的函数的参数传递,然后将该对象传递给指向这些抽象类对象的指针向量?

C++中,继承时,创建子类对象,能否在子类构造函数初始化列表里调用基类构造函数?

scala_类的继承

虚方法抽象方法接口方法