Python Selenium PageObjects框架报错:TypeError: 'tuple' object is not callable 求助
问题分析与解决方案
你遇到的TypeError: 'tuple' object is not callable错误,核心原因是Card类中属性名和方法名重名了,导致方法被属性覆盖,最终调用的是一个不可调用的元组对象。
具体原因拆解
看你的Card类代码:
class Card: def __init__(self,selenium_object): self.selenium_object = selenium_object self.name = Locator.CARD_NAME # 这里赋值的是定位器元组 self.description = Locator.CARD_DESCRIPTION # 同样是元组 self.do = Locator.CARD_DO_BUTTON # 重点:这里把元组赋值给了self.do self.cancel = Locator.CARD_CANCEL_BUTTON self._load() def do(self): # 这里定义的do方法,会被__init__里的self.do元组覆盖 self.selenium_object.find_element(*self.do).click() def cancel(self): # 同理,cancel方法也会被覆盖 self.selenium_object.find_element(*self.cancel).click()
当你实例化Card对象时,__init__方法会先执行,把Locator.CARD_DO_BUTTON这个元组赋值给self.do。之后定义的do()方法根本不会成为实例的方法——因为属性已经占用了这个名称。所以当你调用todos[0].do()时,实际上是在尝试调用一个元组,自然会抛出"tuple不可调用"的错误。
修复方案
把定位器属性的名称和方法名称区分开,比如给定位器属性加上下划线前缀,避免和方法名冲突:
修改后的Card类代码:
class Card: def __init__(self,selenium_object): self.selenium_object = selenium_object # 定位器属性改用下划线前缀,避免和方法名冲突 self._name_locator = Locator.CARD_NAME self._description_locator = Locator.CARD_DESCRIPTION self._do_locator = Locator.CARD_DO_BUTTON self._cancel_locator = Locator.CARD_CANCEL_BUTTON self._load() def do(self): self.selenium_object.find_element(*self._do_locator).click() def cancel(self): self.selenium_object.find_element(*self._cancel_locator).click() def _load(self): # 加载元素文本时使用修改后的定位器属性 self.name = self.selenium_object.find_element(*self._name_locator).text self.description = self.selenium_object.find_element(*self._description_locator).text def __repr__(self): return f'Card(name ="{self.name}", description = "{self.description}")'
额外优化建议
- 你可以把定位器的命名统一风格,比如都用
xxx_locator的格式,这样更清晰,也能避免类似的命名冲突问题。 - 另外,在Todo类中,你直接用
self.webdriver.find_element(*self.name),其实可以复用PageElement类里的find_element方法,写成self.find_element(self.name),这样代码更简洁,也符合PageObject模式的封装思想。
内容的提问来源于stack exchange,提问作者Bruno Lorena
相关产品推荐
相关产品推荐

