Как вернуть различное количество нескольких значений из функции Python - PullRequest
0 голосов
/ 24 апреля 2020

У меня есть устаревшая иерархия классов, которую я хочу расширить новым классом с другой сигнатурой метода: переопределенный метод должен возвращать значения дерева вместо двух. Третье возвращаемое значение для устаревших классов должно быть некоторым значением по умолчанию. Пример ниже ( repl.it ).

class BaseClass:
    def do_work(self):
        param1, param2, param3 = self.get_params()
        self._process(param1, param2, param3)

    def get_params(self):
        # this method shoud be overrided in the child class
        raise NotImplementedError()

    def _process(self, param1, param2, param3):
        # do some process, for example, print params
        print(param1, param2, param3)


class LegacyChild(BaseClass):
    def get_params(self):
        return 1, 2, 3


class NewChild(BaseClass):
    def get_params(self):
        return 1, 2


legacy_child = LegacyChild()
legacy_child.do_work()

new_child = NewChild()
new_child.do_work()

В этом случае я получаю ValueError: not enough values to unpack (expected 3, got 2) на третьей строке. И это правильно.

Моей первой мыслью, чтобы решить эту проблему, было изменить три жестко закодированных параметра на кортеж переменной длины, а затем установить param1, param2 и param3 в зависимости от его длины:

class BaseClass:
    def do_work(self):
        params = self.get_params()

        if len(params) == 3:
            param1, param2, param3 = params
        else:
            param1, param2 = params
            param3 = 3  # some default value

        self._process(param1, param2, param3)

    def get_params(self):
        # this method shoud be overrided in the child class
        raise NotImplementedError()

    def _process(self, param1, param2, param3):
        # do some process, for example, print params
        print(param1, param2, param3)

Я думаю, что это решение слишком грубое ( repl.it ).

Есть ли другое возможное решение этой проблемы?

1 Ответ

1 голос
/ 24 апреля 2020

Может быть, это?

param1, param2, *param3 = self.get_params() # param3 is an array. When there are only 2 elements, it's empty.
self._process(param1, param2, (param3 or [3])[0]) # 3 is the default value

Это предполагает, что get_params всегда будет производить 2 или 3 элемента. Его нельзя легко расширить для обработки методов, которые возвращают только один элемент.

...