我正在使用大量现有的Python代码库,并希望开始添加类型注释,以便我可以进行一定程度的静态检查。我想象的是Erlang,Strongtalk或Typed Scheme/Racket。
我见过快速和脏的装饰器,它们根据函数参数和返回类型注释插入动态检查,但我正在寻找更强大的东西并在编译时执行检查。
现在有哪些工具可用于此类事情?我熟悉编译器和类型检查,如果它具有良好的基础,我绝对愿意改进一个不完整的工具。
(注意:我对讨论静态类型的优缺点不感兴趣。)
编辑:一个例子:
def put(d, k, v):
d[k] = v
我希望能够将put
函数注释为类型put<K,V>(dict<K,V>, K, V) -> None
。
更新:新的PEP 484(2014年9月)定义了Python 3.5+中静态类型和类型注释的标准。有一个名为mypy的类型检查工具,它与PEP 484兼容。
答案 0 :(得分:16)
编辑2016-11-11:只需使用mypy即可。可以逐渐添加类型提示。在Python 3源代码中,它验证标准PEP 484类型提示。类型仍然可以使用特殊注释在Python 2中表达。 Guido likes it
这篇文章最初是在很久以前写的,之前是mypy。我保留了帖子下面的原始内容,即使它不太准确。
原帖:
您可能想查看此related StackOverflow post on static analysis for Python中提到的一些项目。
总结:
由于Python广泛使用duck typing,在其他语言中可能被称为“类型错误”的东西可能最终成为“对象 X 不支持方法 Y “在Python中。
编辑2011-05-17:
我同意delnan的说法,Python [显然错误] 无法进行静态输入。但由于我们的怀疑似乎并没有阻止你,我只能给你更多有关这个问题的信息。我提出:
答案 1 :(得分:9)
您可能会发现mypy很有趣。它一直是proposed for inclusion in Python 3.5 by Guido。
答案 2 :(得分:6)
查看此帖子:PySonar: a Static Analyzer for Python。 PySonar是一种使用代码的抽象解释(部分执行)推断类型的工具。它找到程序的所有可能的执行路径,并找到所有可能的变量类型。
基本上有三个版本的PySonar:
它们都没有(封闭源代码除外)完全实现。但基本的想法是你可以用它作为你工作的基础。
答案 3 :(得分:3)
我不知道这是否有所帮助,但是对于它的价值,科罗拉多大学的Jeremy Siek做了一些逐步打字的工作,我发现这很快就做了。 http://www.wiki.jvmlangsummit.com/pdf/28_Siek_gradual.pdf
我的猜测(我可能错了)是因为他的研究看起来相对较新,所以目前没有任何有前途的开源工具。
您最好的选择可能是联系作者并询问他们是否可以向您发布代码。
答案 4 :(得分:2)
Python 3有'渐进'包;请参阅PIP或Bitbucket Repo
显然,这是Jeremy Siek周围小组的实施,他们似乎是逐渐打字领域的权威。
有些注释显然是必要的,这是一个例子:
from gradual import *
@typed
def calculate_total(a:int, b:int) -> int:
return a + b//100
就注释而言,这并不是那么糟糕。我没有使用过软件包,所以我不能说它的质量,但语法(以及它背后的人)肯定会让它看起来很有希望。
答案 5 :(得分:2)
我喜欢prospector的后端landscape.io。它将现有分析仪的输出(例如pylint,pyflakes,pep8,frosted ......)组合到一个报告中。整齐。
答案 6 :(得分:1)
前段时间我有类似的需求。 我发现的所有现有解决方案都存在一些问题,或者没有我想要的功能,所以我自己做了。
以下是您使用它的方式:
from requiretype import require
@require(name=str, age=(int, float, long))
def greet_person(name, age):
print "Hello {0} ({1})".format(name, age)
>>> greet_person("John", 42)
Hello John (42)
>>> greet_person("John", "Doe")
# [...traceback...]
TypeError: Doe is not a valid type.
Valid types: <type 'int'>, <type 'float'>, <type 'long'>
>>> greet_person(42, 43)
# [...traceback...]
TypeError: 42 is not a <type 'str'> type
我希望这对你有用。
有关详细信息,请参阅:
P.S。:(引自github repo)
对于大多数情况,我建议使用测试而不是类型检查,因为在Python中这样做更自然。但是,在某些情况下,您需要/需要指定要使用的特定类型,因为python没有对参数进行类型检查,这是有用的。