Python - реализовать ПОЛЬЗОВАТЕЛЬСКИЙ метод "lshift" - но не для элементов bitarray - PullRequest
0 голосов
/ 15 мая 2019

У меня есть класс, который имеет в качестве параметра список целочисленных значений.Я должен реализовать пользовательский метод lshift , который будет выполнять добавление в список (я должен переопределить метод lshift для моего варианта использования).Это пользовательский метод lshift, поэтому он не имеет ничего с bitarrays , а работает только с целыми числами в списке (добавляя его в список) и получает аргумент element .Я должен сделать это без import дополнительных классов Python.Я также определил тесты для этой функциональности, чтобы вы могли видеть, как должен выглядеть результат.(Я уже реализовал пользовательские методы для add, len и iter , но я полагаю, что это не имеет значения)

class CustomShift:

    def __init__(self, iterator=None):
        self.iterator = iterator
        if (self.iterator):
            self.iterator = list(dict.fromkeys(self.iterator))

    def __lshift__(self, element):
        """Add an element to the list.

        >>> shiftInstance = CustomShift()
        >>> _ = shiftInstance << 4
        >>> sorted(shiftInstance << 5 << 6 << 4)
        [4, 5, 6]
        """
        if self.iterator is None:
            self.iterator = []
            if element:
                self.iterator.append(element)

if __name__ == "__main__":
    import doctest
    from pprint import pprint
    doctest.testmod()

первые два теста пройдены, но третий не пройден!

TypeError: unsupported operand type(s) for <<: 'NoneType' and 'int'

Не уверен, что я делаю неправильно, любой намек будет оценен.Заранее спасибо

1 Ответ

1 голос
/ 15 мая 2019

Прежде всего, __lshift__ необходимо вернуть значение - даже если оно изменяет экземпляр, над которым работает.Чтобы цепочка работала так, как вы ожидаете, она должна возвращаться сама собой.Поскольку первая операция << ничего не возвращает, любые последующие операции приведут к исключению TypeError, которое вы заметили.

Во-вторых, метод __lshift__ имеет логическую ошибку - элемент только добавляетсяесли аргумент iterator равен None.Таким образом, в самом общем случае использования, который вы намереваетесь, на самом деле ничего не произойдет.

Наконец, в вашем тестовом примере вы хотите вызвать sort для объекта, что подразумевает, что этот объект должен предоставлять какой-то итератор (через __iter__), иначе просто не получится с TypeError: 'CustomShift' object is not iterable.Если сложить это вместе, ваш класс будет выглядеть так:

class CustomShift:

    def __init__(self, iterator=None):
        self.iterator = iterator
        if (self.iterator):
            self.iterator = list(dict.fromkeys(self.iterator))

    def __lshift__(self, element):
        """Add an element to the list.

        >>> shiftInstance = CustomShift()
        >>> _ = shiftInstance << 4
        >>> sorted(shiftInstance << 5 << 6 << 4)
        [4, 5, 6]
        """
        if self.iterator is None:
            self.iterator = []
        if element:
            self.iterator.append(element)
        return self

    def __iter__(self):
        return iter(self.iterator)

Однако тест все равно не пройден, поскольку в его структуре shiftInstance уже добавлен 4, назначенный _.

Failed example:
    sorted(shiftInstance << 5 << 6 << 4)
Expected:
    [4, 5, 6]
Got:
    [4, 4, 5, 6]

Это, однако, должно направить вас в направлении того, как вы можете исходить из того, что получили.

...