如何动态选择python基类?

时间:2017-09-26 14:01:53

标签: python selenium inheritance

在python(3)中,我想从几个基类动态创建一个派生类。

具体示例:在selenium中,为了运行基于GUI的测试,您可以通过以下方式从Firefox或Chrome启动驱动程序:

driver = webdriver.Firefox()
driver = webdriver.Chrome()

现在我想创建一个添加了附加功能的派生类。像

这样的东西
class MyDriver(webdriver.Firefox):
    def find_button_and_click_on_it_no_matter_what(self, params):
        ...

但基类可以是firefox驱动程序,也可以是chrome driver。我找到了与here相关的内容,但它似乎不起作用:

class MyDriver(object):
    def __new__(cls, base_type, *args, **kwargs):
        return super(HBPDriver, cls).__new__(base_type, *args, **kwargs)

    def __init__(self):
        pass

调用此命令

driver = mydriver.MyDriver(webdriver.Firefox())    

给出错误

TypeError: object.__new__(X): X is not a type object (WebDriver)

怎么做对了?以及如何在派生类上调用__init__ ...?

我希望很清楚我想要实现的目标......

1 个答案:

答案 0 :(得分:2)

当你调用__new__时,选择要实例化的类为时已晚; __new__是该类的属性。相反,你需要一个简单的工厂功能:

def my_driver(cls, *args, **kwargs):
    class NewThing(cls):
        ...
    return NewThing(*args, **kwargs)

ff = my_driver(webdriver.Firefox)

另一种选择是使用表达式

定义基类
if ...:
  base = webdriver.Firefox
elif ...:
  base = webdriver.Chrome
class MyDriver(base):
    ...

第三个选项是跳过class语句并直接使用type,但我不建议这样做,除非类声明的主体是空的。

class MyDriver(base):
    pass

相当于MyDriver = type('MyDriver', (base,), {})