Iterable 模拟在 Transcrypt 中的应用

3
我一直在尝试将一个向量数学库移植到transcrypt,但在模拟可迭代类型时遇到了问题。
我有一个带有内部可迭代的向量类。以下是核心代码的简化版本:
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)))

在纯python中,(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)))

但是,我觉得将其与内部容器耦合在一起感觉不太稳定,我认为创建迭代器和starmap存在开销。

那么,如何解决这个问题呢?我可以在类中添加map()吗?如果可以,正确的签名是什么?底层的JS似乎依赖于JS作用域行为...这让我感到害怕...

1个回答

0
问题在于 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开关激活迭代器)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接