经常声明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静态输入?或者这实际上是错误的?
答案 0 :(得分:14)
那么,函数参数是否也算作变量?
他们当然可以。他们总是使用几乎所有语言。
或者在什么意义上RPython静态输入?或者这实际上是错误的?
声明是正确的。 RPython不是Python。嗯,它是它的一个子集,可以作为Python代码运行。但是当你真正编译RPython代码时,会有很多动态性被带走(尽管只是在导入时间之后,所以你仍然可以使用元类,从字符串生成代码等等 - 在某些模块中用得很有效)编译器(这是不 Python编译器,但与传统编译器有很大不同;请参阅相关文档)确实可以确定静态使用的类型。更准确地说,使用动态性的代码使它通过解析器和所有内容,但在某些时候会导致类型错误。
在许多情况下,可能是编译器可以证明函数参数只能是某些类型,但绝对不是在所有情况下。
当然不是。有很多代码不是静态类型的,而且很多静态类型的代码当前的注释器无法被证明是静态类型的。但是当这样的代码被发现时,它就是编译错误,句号。
有几点很重要:
推断类型,未明确说明(嗯,大多数情况下;我相信有一些函数需要断言来帮助注释器)。静态类型不会(正如您在评论中暗示的那样)意味着必须写出类型(称为清单类型),这意味着每个表达式(包括变量)都有一个永不改变的类型。
所有分析都是在整个程序的基础上进行的!无法推断函数def add(a, b): return a + b
的(非泛型)类型(参数可能是int,浮点数,字符串,列表等),但是如果使用整数参数调用函数(例如整数文字或先前推断为包含整数的变量),确定a
和b
(以及+
的类型,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,但文档仍然是一个很好的起点。读了一下之后,最好的办法就是尝试翻译一些代码,你会弄清楚你能做什么,不能做得很快!