在RPython中静态输入什么?

时间:2011-08-23 13:36:49

标签: python static-typing pypy rpython

经常声明RPython(Python的一个子集)是静态类型的。 (例如Wikipedia。)

最初,我想知道他们会如何将它添加到Python中,并认为他们可能已经添加了在每个函数的开头添加assert isinstance(arg1, ...)等语句的要求(但我真的不相信)。

然后我查看了一些RPython代码,它看起来并没有真正的静态类型。在许多情况下,可能是编译器可以证明函数参数只能是某些类型,但绝对不是在所有情况下。

,例如,这是string.split的RPython实现:

def split(value, by, maxsplit=-1):
    bylen = len(by)
    if bylen == 0:
        raise ValueError("empty separator")

    res = []
    start = 0
    while maxsplit != 0:
        next = value.find(by, start)
        if next < 0:
            break
        res.append(value[start:next])
        start = next + bylen
        maxsplit -= 1   # NB. if it's already < 0, it stays < 0

    res.append(value[start:len(value)])
    return res

在关于RPython的PyPy文档中,有人说:“变量应包含最多一种类型的值”。

那么,函数参数也算作变量吗?或者在什么意义上RPython静态输入?或者这实际上是错误的?

2 个答案:

答案 0 :(得分:14)

  

那么,函数参数是否也算作变量?

他们当然可以。他们总是使用几乎所有语言。

  

或者在什么意义上RPython静态输入?或者这实际上是错误的?

声明是正确的。 RPython不是Python。嗯,它是它的一个子集,可以作为Python代码运行。但是当你真正编译RPython代码时,会有很多动态性被带走(尽管只是在导入时间之后,所以你仍然可以使用元类,从字符串生成代码等等 - 在某些模块中用得很有效)编译器(这是 Python编译器,但与传统编译器有很大不同;请参阅相关文档)确实可以确定静态使用的类型。更准确地说,使用动态性的代码使它通过解析器和所有内容,但在某些时候会导致类型错误。

  

在许多情况下,可能是编译器可以证明函数参数只能是某些类型,但绝对不是在所有情况下。

当然不是。有很多代码不是静态类型的,而且很多静态类型的代码当前的注释器无法被证明是静态类型的。但是当这样的代码被发现时,它就是编译错误,句号。

有几点很重要:

  • 推断类型,未明确说明(嗯,大多数情况下;我相信有一些函数需要断言来帮助注释器)。静态类型不会(正如您在评论中暗示的那样)意味着必须写出类型(称为清单类型),这意味着每个表达式(包括变量)都有一个永不改变的类型。

  • 所有分析都是在整个程序的基础上进行的!无法推断函数def add(a, b): return a + b的(非泛型)类型(参数可能是int,浮点数,字符串,列表等),但是如果使用整数参数调用函数(例如整数文字或先前推断为包含整数的变量),确定ab(以及+的类型,add的结果)也是整数

  • 并非PyPy存储库中的所有代码都是RPython。例如,有代码生成器(例如在rlib.parsing中)在编译时运行并生成RPython代码,但不是RPython(顺便说一句,通常带有"NOT_RPYTHON" docstring)。此外,标准库的大部分内容都是用完整的Python编写的(大部分直接来自CPython)。

关于整个翻译和打字的实际​​工作方式,有很多非常有趣的材料。例如,The RPython Toolchain描述了一般的翻译过程,包括类型推断,The RPython Typer描述了所使用的类型系统。

答案 1 :(得分:4)

是的,它是静态类型的。在您的示例中,没有变量更改类型,这满足了RPython在这方面的要求。 RPython is not formally defined, and it's restrictions are constantly evolving,但文档仍然是一个很好的起点。读了一下之后,最好的办法就是尝试翻译一些代码,你会弄清楚你能做什么,不能做得很快!