子类通用的关键是用**kwargs透传父类参数并显式声明专属参数:先接收不确定的父类参数并用super().__init__(**kwargs)转发,再单独定义子类所需参数,避免硬编码;多重继承时必须用super()确保按mro顺序完整初始化。

子类要通用,关键不是把所有参数都写死在 __init__ 里,而是让父类参数能“透传”过去,同时还能加自己的专属参数。核心就两点:用 **kwargs 接收不确定的父类参数,再用 super().__init__(**kwargs) 转发;自己需要的参数单独定义。
用 **kwargs 实现父类参数自动透传
父类参数可能变、可能多,硬编码每个参数名会卡死子类复用性。直接用 **kwargs 把所有关键字参数打包接收,再原样交给父类初始化:
- 父类定义:
class BasePage: def __init__(self, driver, timeout=10): ... - 子类写法:
class LoginPage(BasePage): def __init__(self, **kwargs): super().__init__(**kwargs) - 实例化时:
LoginPage(driver=driver, timeout=15)或LoginPage(driver=driver)都行,不用改子类代码
子类专属参数要显式声明
只靠 **kwargs 不够——你得清楚哪些是子类自己要用的。把它们单独列出来,既明确意图,也避免被误传给父类:
- 例如登录页要额外记下用户名字段定位器:
class LoginPage(BasePage): def __init__(self, locator_user, **kwargs): super().__init__(**kwargs); self.locator_user = locator_user - 调用时:
LoginPage(locator_user=('id', 'username'), driver=driver) - 这样
locator_user被子类处理,其余参数(如driver、timeout)全进**kwargs交给父类
避免混用 *args 和 **kwargs 的陷阱
位置参数(*args)和关键字参数(**kwargs)顺序不能乱。Python 要求 *args 必须在 **kwargs 前面,且子类签名要兼容父类预期:
- 错误写法:
def __init__(self, **kwargs, extra):—— 语法报错 - 正确写法:
def __init__(self, extra, **kwargs):或def __init__(self, *args, **kwargs): - 如果父类用位置参数(比如
__init__(self, url)),子类也需用*args接收,再按顺序传给super()
多重继承时必须用 super(),别手动调父类名
多个父类共存时(比如同时继承 BasePage 和 RetryMixin),手动写 BasePage.__init__(self, ...) 会跳过某个父类的初始化。只有 super() 按 MRO 顺序依次调用,确保全部执行:
class SmartLogin(BasePage, RetryMixin): def __init__(self, **kwargs): super().__init__(**kwargs)- 哪怕两个父类都有
__init__,super()也能保证都走一遍,不漏不重











