通常说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在什么意义上是静态类型的?或者这实际上是错误的陈述?在
当然有。几乎每种语言都有。在
这个说法是正确的。RPython不是Python。好吧,它是Python的一个子集,可以作为Python代码运行。但是,当您实际编译RPython代码时,您将失去太多的动态性(尽管只是在导入时间之后,因此您仍然可以使用元类、从字符串生成代码等-在某些模块中使用效果非常好),因此编译器(即不是Python编译器,但与传统编译器有很大不同;请参见相关文档)确实可以决定静态使用类型。更准确地说,使用动态性的代码会使其通过解析器和其他一切,但在某些时候会导致类型错误。在
当然不是。有很多代码不是静态类型的,还有相当多的静态类型代码当前的注释器无法证明是静态类型的。但是,当这样的代码不完整时,就是一个编译错误,句号。在
有几点需要注意:
类型是推断出来的,不是显式声明的(好吧,在大多数情况下,我相信有一些函数需要断言来帮助注释器)。静态类型并不意味着必须写出类型(这称为清单类型),它意味着每个表达式(包括变量)都有一个永远不变的类型。
所有这些分析都是在整个程序的基础上进行的!不能推断函数}(并且,根据
def add(a, b): return a + b
(参数可能是int、float、string、list等)的(非泛型)类型,但是如果函数是用整型参数(例如,以前推断为包含整数的整型文本或变量)调用的,则可以确定a
和{+
的类型,结果add
)也是整数。并非PyPy存储库中的所有代码都是RPython。例如,有一些代码生成器(例如,
rlib.parsing
)在编译时运行并生成RPython代码,但不是RPython(顺便说一下,通常使用"NOT_RPYTHON"
docstring)。另外,标准库的大部分内容都是用完整的Python编写的(大部分直接取自CPython)。有很多关于整个翻译和打字的非常有趣的材料。例如,The RPython Toolchain一般描述转换过程,包括类型推理,The RPython Typer描述使用的类型系统。在
是的,它是静态类型的。在您的示例中,没有任何变量更改类型,这符合RPython在这方面的要求。RPython is not formally defined, and it's restrictions are constantly evolving,但是文档仍然是一个很好的起点。读了一点之后,最好的办法就是试着翻译一些代码,你会很快发现你能做什么和不能做什么!在
相关问题 更多 >
编程相关推荐