Итеративная эмуляция в транскрипте

Я пытался портировать библиотеку векторной математики для транскрипции и столкнулся с проблемой эмуляции итерируемых типов.

У меня есть класс Vector с внутренней итерацией. Вот упрощенная версия ядра:

class Vector:
    def __init__(self, *values):
        self.values = values

    def __iter__(self):
        for item in self.values:
            yield item

    def __add__(self, other):
        return Vector( *(x + y for x, y in zip(self, other)))

В чистом питоне (Vector(1,2,3) + Vector(3,4,5)) возвращается Vector(4,6,8) как и следовало ожидать. Но после транскрипции тот же код не работает - в Javascript кажется, что zip() ожидает Javascript map() функционировать на своих повторяемых объектах.

В этом случае я могу обойти это, явно нацеливаясь на базовое хранилище, которое - поскольку оно создано с помощью * args - похоже, имеет требуемый метод:

def __add__(self, other):
    pairwise = zip(self.values, other.values)
    return Vector( *(itertools.starmap(lambda a, b: a + b, pairwise)))

но связывание этого с внутренним контейнером кажется мне шатким, и я предполагаю, что на создание итератора и карты звездочек уходит много времени.

Итак - как правильно обойти это? Могу ли я добавить map() к классу? И если да, то какая правильная подпись? Основной JS, кажется, полагается на JS scoping поведение... что пугает меня...

1 ответ

Дело в том, что zip еще не был адаптирован для итераторов. Простой обходной путь - преобразование аргументов zip в списки. Следующий код работает:

class Vector:
    def __init__(self, *values):
        self.values = values

    def __iter__(self):
        for item in self.values:
            yield item

    def __add__(self, other):
        return Vector( *(x + y for x, y in zip(list (self), list (other))))

    def __str__ (self):
        return self.values

#__pragma__ ('opov')

print (Vector(1,2,3) + Vector(3,4,5))

#__pragma__ ('noopov')

Это напечатает:

4,6,8

Извините за поздний ответ, были немного тонко распространены в последние несколько месяцев. Адаптировать zip для итераторов я нашел довольно сложным, поэтому это еще не сделано.

Если подумать, преобразование параметров в списки может быть сделано автоматически. Я добавлю это (проблема № 369), несмотря на (крошечные) издержки теста времени выполнения, поскольку он лучше соответствует ожидаемому поведению.

Он находится в выпуске 3.6.44, и теперь ваш код должен работать правильно без изменений (используйте ключ -e 6 для активации итераторов).

Другие вопросы по тегам