从robotframe工作中的不同类调用同名的python函数

时间:2018-11-13 09:59:36

标签: python robotframework

我有一个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

有人可以指导我该怎么做吗?

2 个答案:

答案 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