如何在代码中初始化一个可编译为pypy的rpython的set()?

6 投票
2 回答
2765 浏览
提问于 2025-04-16 10:16

我想用pypy的rpython翻译器来编译一些python代码。这是一个非常简单的示例,实际上什么都不做:

def main(argv):
 a = []
 b = set(a)
 print b
 return 0

def target(driver,args):
        return main,None

如果我这样编译:

python2.6 ~/Downloads/pypy-1.4.1-src/pypy/translator/goal/translate.py --output trypy trypy.py 

它就不能编译,而是会出现一些错误,像这样:

[translation:ERROR]  AttributeError': 'FrozenDesc' object has no attribute 'rowkey'
[translation:ERROR]  .. v1 = simple_call((type set), v0)
[translation:ERROR]  .. '(trypy:3)main'
[translation:ERROR] Processing block:
[translation:ERROR]  block@0 is a <class 'pypy.objspace.flow.flowcontext.SpamBlock'>
[translation:ERROR]  in (trypy:3)main
[translation:ERROR]  containing the following operations:
[translation:ERROR]        v0 = newlist()
[translation:ERROR]        v1 = simple_call((type set), v0)
[translation:ERROR]        v2 = str(v1)
[translation:ERROR]        v3 = simple_call((function rpython_print_item), v2)
[translation:ERROR]        v4 = simple_call((function rpython_print_newline))
[translation:ERROR]  --end--

如果我把set()这个函数去掉,它就能正常工作。那么在rpython中怎么使用集合呢?

2 个回答

0

虽然RPython不认识set这个东西,但它可以导入Sets模块。

我可能说得有点早。sets模块使用了三参数的getattr调用,而RPython不支持这个可选的第三个参数。

这个问题可以通过以下步骤解决:

  1. 在pypy的安装目录下,找到lib-python\2.7\,把sets.py复制到你的项目目录,并把复制的文件改名为rsets.py
  2. 在这个文件里,找到五个getattr的使用地方。把最后一个参数(默认返回值)去掉,这个参数在每个地方都是None
  3. 在你的RPython代码前面加上from rsets import Set as set

在这五个地方,如果元素不能被哈希,它会返回AttributeError而不是TypeError,但其他地方的功能会正常。

4

所以官方确认了,set()在rpython中是不支持的。感谢TryPyPy。

撰写回答