我有一个python类,它继承了多个类,并且具有相同名称的 test_func()
parent.py
class parent:
def __init__(self, **kwargs):
self.ip = kwargs.get('ip')
self.name = kwargs.get('name')
self.local = kwargs.get('local')
class child1(parent):
def __init__(self,**kwargs):
parent.__init__(self,**kwargs)
def test_func(self):
print 'When local =true'
return self.name
class child2(parent):
def __init__(self,**kwargs):
parent.__init__(self,**kwargs)
def test_func(self):
print ("When local =False")
return self.ip
class child3(parent,child1,child2):
def __init__(self, **kwargs):
parent.__init__(self, **kwargs)
有一个环境文件,我在其中初始化课程
from parent import parent
from child2 import child2
from child1 import child1
from parent import child3
server=child3(
ip = '10.20.11.10',
name ='pankaj',
local = False
)
我有一个机器人文件( Test.robot ),该文件调用方法test_func
*** Settings ***
Library parent.child3 WITH NAME wireshark_test
*** Variables ***
*** Test Cases ***
This is first
Invoking methods
*** Keywords ***
Invoking methods
log to console wireshark_test.test_func
我正在通过命令
执行此操作pybot -V envSI.py Test.robot
我总是得到child1类的test_func
期望:
当 child1 类的 local = True test_func 时 其他 child2 类的 test_func
有人可以指导我该怎么做吗?
答案 0 :(得分:3)
我总是得到child1类的test_func
之所以如此,是因为Method Resolution Order在python中具有多重继承;另一种读法是https://www.python.org/download/releases/2.3/mro/(不要介意url中的旧版本)。
简而言之,当存在多重继承时-如您的示例class child3(parent,child1,child2)
,当可以访问属性时,python将从左到右在父类中查找,直到找到匹配项(并提高匹配度)一个例外,如果没有的话。)
当您调用test_func()
时,解决方案从“父级”(未找到)开始,然后转到“ child1”。由于具有此方法,因此选择并执行了该解决方案。因此,对于从“ child3”创建的对象,它将始终是“ child1”中的实现。
您可以更改MRO吗?几乎没有(而且,如果您不确定101%的工作,那么您真的不想这样做)。您可以更改类的继承模式。或者您可以拥有不同的类对象-“ child1”和“ child2”,然后根据您的情况调用相应的对象。
答案 1 :(得分:2)
基于@todor的上述答案。我观察到的是,没有逻辑确定如何实例化正确的类。通常,此逻辑将驻留在某些工厂类中,但假设确定类的逻辑很简单,则下面的示例将使您可以使用动态类名来执行所需的操作。
robot_suite.robot
*** Test Cases ***
TC - false
Import Library child3
... ip=10.20.11.10
... name=pankaj
... local=false
... WITH NAME i_false
${result} i_false.Test Func
Should Be Equal As Strings ${result} 10.20.11.10
TC - true
Import Library child3
... ip=10.20.11.10
... name=pankaj
... local=true
... WITH NAME i_true
${result} i_true.Test Func
Should Be Equal As Strings ${result} pankaj
由于一个库的实例化只能执行一次,因此我使用WITH NAME
构造将同一库加载两次。
child3.py
class child3(object):
def __init__(self, **kwargs):
self.child = globals()["child_" + kwargs.get('local', 'true')](**kwargs)
def get_keyword_names(self):
return ['test func']
def run_keyword(self, name, args):
return getattr(self.child, name.lower().replace(' ', '_'))()
class parent:
def __init__(self, **kwargs):
self.ip = kwargs.get('ip', 'Default')
self.name = kwargs.get('name', 'Default')
self.local = kwargs.get('local', 'Default')
class child_true(parent):
def __init__(self,**kwargs):
parent.__init__(self,**kwargs)
def test_func(self):
return self.name
class child_false(parent):
def __init__(self,**kwargs):
parent.__init__(self,**kwargs)
def test_func(self):
return self.ip