Вызов функций Python с одинаковыми именами из разных классов в работе робота - PullRequest
0 голосов
/ 13 ноября 2018

У меня есть класс 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)

Имеется файл environment , в котором я инициализирую класс

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

Я всегда получаю test_func класса child1

Ожидание:

Когда local = True test_func из child1 класс Else test_func из child2 class

Кто-нибудь может подсказать, пожалуйста, как мне это сделать?

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Опираясь на ответ выше @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
0 голосов
/ 13 ноября 2018

Я всегда получаю test_func класса child1

Это так из-за порядка разрешения методов в множественном наследовании в python;другое чтение - https://www.python.org/download/releases/2.3/mro/ (не обращайте внимания на старую версию в URL).

Короче говоря, когда есть множественное наследование - как в вашем примере, class child3(parent,child1,child2), когда есть доступ к атрибуту, python будет смотреть в родительские классы слева направо, пока не будет найдено совпадение (ивызовите исключение, если его нет).
Когда вы вызывали test_func(), разрешение начиналось с «parent» - не найдено, затем переходило к «child1» - и, поскольку у него есть этот метод, оно выбиралосьи выполнен.И, таким образом, для объектов, созданных из «child3», это всегда будет реализация в «child1».

Можете ли вы изменить MRO?Вряд ли (и вы действительно не хотите этого делать, если не уверены на 101% в том, что делаете).Вы можете изменить шаблоны наследования класса;или вы можете иметь разные объекты классов - «child1» и «child2» и вызывать соответствующий в зависимости от вашего состояния.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...