RPython中的静态类型是什么?

RPython中的静态类型是什么?,python,static-typing,pypy,rpython,Python,Static Typing,Pypy,Rpython,人们常说(Python的子集)是静态类型的。(例如,打开。) 起初,我想知道他们将如何将其添加到Python中,并认为他们可能已经添加了在每个函数的开头添加诸如assert-isinstance(arg1,…)等语句的要求(但我真的不相信这一点) 然后我看了一些RPython代码,它看起来根本不是静态类型的。在许多情况下,编译器可能会证明函数参数只能是某些类型,但肯定不是所有情况下都可以 例如,这是string.split的RPython实现: def split(value, by, maxs

人们常说(Python的子集)是静态类型的。(例如,打开。)

起初,我想知道他们将如何将其添加到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
def split(值,按,maxslit=-1):
bylen=len(by)
如果bylen==0:
提升值错误(“空分隔符”)
res=[]
开始=0
而maxsplit!=0:
下一步=值。查找(按,开始)
如果next<0:
打破
res.append(值[开始:下一步])
开始=下一步+下一步
maxsplit-=1#NB。如果它已经<0,它将保持<0
res.append(值[开始:len(值)])
返回res
在关于RPython的PyPy文档中,有这样一句话:“变量最多应该包含一种类型的值”


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

是的,它是静态输入的。在您的示例中,所有变量都不会改变类型,这符合RPython在这方面的要求,但是文档仍然是一个很好的起点。在读了一点之后,最好的办法就是尝试翻译一些代码,你会很快发现你能做什么和不能做什么

那么,函数参数也算作变量吗

当然有。几乎每种语言都有

或者RPython在什么意义上是静态类型的?或者这真的是错的

这句话是正确的RPython不是Python。嗯,它是Python的一个子集,可以作为Python代码运行。但是,当您实际编译RPython代码时,会失去太多的动态性(尽管只是在导入之后,所以您仍然可以使用元类,从字符串生成代码,等等——在某些模块中使用非常有效),编译器(这是而不是Python编译器,但与传统编译器有很大不同;请参阅相关文档)确实可以确定类型是静态使用的。更准确地说,使用动态性的代码会通过解析器和所有程序,但会在某个时候导致类型错误

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

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

有几点是必须认识到的:

  • 类型是推断出来的,而不是显式声明的(好吧,在大多数情况下;我相信有一些函数需要断言来帮助注释者)。静态类型并不意味着必须写出类型(即所谓的清单类型),它意味着每个表达式(包括变量)有一个永远不会更改的单一类型

  • 所有这些分析都是在整个程序的基础上进行的!不能推断函数的(非泛型)类型
    def add(a,b):返回a+b
    (参数可能是整数、浮点数、字符串、列表等),但如果函数是用整数参数调用的(例如整数文本或先前推断为包含整数的变量),确定
    a
    b
    (并且,根据
    +
    的类型,
    add
    的结果)也是整数

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


关于整个翻译和键入的实际工作原理,有很多非常有趣的材料。例如,描述了一般的翻译过程,包括类型推断,并描述了类型系统已使用。

但不更改类型和静态类型是不同的。我在示例中看到,变量不更改其类型,但它们不是静态类型。在翻译类型推断过程中,您不必显式定义变量的类型。该URL似乎不再起作用。了解实际上的限制是。啊,在整个程序的基础上,这个位[静态类型]是我认为这里最重要的一位。因为,在您编写时,函数
def添加(a,b):return a+b
不是静态类型,甚至可以用于几种不同的类型。@Albert:请看我的编辑,以回应您对zeekay答案的评论。您可能已经被一个古老而流行的错误观念绊倒了,即静态类型是显式类型。