【问题标题】:Python compile time type checkingPython 编译时类型检查
【发布时间】:2013-04-18 21:47:18
【问题描述】:

Python 不会在编译时检查类型,因为它不能,至少在某些情况下是这样。但是有没有人想出一种机制来根据用户的额外注释进行编译时类型检查?像 pylint 这样的东西使用作者的额外保证?我正在考虑类似的事情:

#guarantee(argument=int, return_type=int)
def f(x):
    return x + 3

#guarantee(argument=int, return_type=str)
def g(x):
    return "%d times" % x

y = f(6)

# works, z = "9 times"
z = g(y)
# error
a = f(z)

此检查器将解释每个函数上方的 cmets,意识到 f(x) 应该只接受 int 但 z 来自 g(x),所以它是 str。有没有类似的产品?

【问题讨论】:

  • 我的理解是 PyPy 做的事情有点像这样,但一般来说,人们不会尝试取消 Python,而是使用严格类型的语言。此外,无论如何,Python 中并没有真正意义上的“编译时”。您可以进行静态或动态代码分析,转换为 pyc 可以视为编译,但从根本上讲,任意代码可以在运行时更改系统的任何内容。

标签: python static-analysis pylint


【解决方案1】:

PEP 3107 最近完成了(最近是在去年的某个时候),它为变量和函数引入了注释。不幸的是(从 pep 的数量可以看出)这仅适用于 Python 3.x,因此您编写的任何检查器(甚至代码)都将仅适用于 Python 3(这确实不是一件坏事)。

您提到了 pylint,所以我假设您实际上并不希望在编译时运行检查,而是在编译后进行检查。这将是一个很棒的工具,可以在 code-quality mailing list 讨论。

【讨论】:

  • @noisecapella 很高兴为您提供帮助
【解决方案2】:

我认为您缺少的关键字是decorator

您可以编写自己的装饰器来执行以下操作:

@check(bar=int)
foo(bar):
    pass

您可以查看示例实现here。虽然这对于编译检查当然无效,因为它是在运行时完成的。

【讨论】:

  • 是的,我曾经实现过这样的事情。在实现这些装饰器时,一个不太酷的问题是让 IDE 知道您所做的事情,因此代码建议可能会变得混乱 - 不知道他们是否在您的示例中这样做了。编辑:不,这就是问题所在,如果您'只是传递 *args 和 **kwargs,代码建议会在翻译中丢失:P
【解决方案3】:

我不确定这是对 Python 中现有运行时机制的重大改进。例如,

def f(x):
    if not isinstance(x, int):
        raise TypeError("Expected integer")
    return x + 3

def g(x):
    return "%d times" % x

# Works.
y = f(6)
z = g(y)
# Fails, raises TypeError.
a = f(z)

换句话说,如果不对 Python 中每个对象的每个函数和每个方法进行注释,就很难静态地确定 fg 的返回类型是什么。我怀疑任何沿着这些思路的静态检查器都会有任何价值。

即使您在函数中添加了返回类型描述符,这真的是一种保证吗?它看起来很像可能无法与代码一起更新的文档,从而导致以后由于不正确的假设而导致更隐蔽的错误。

【讨论】:

  • 那么当对象被视为其他类型时(通过__str____nonzero__ 等)呢? Python 在基础层面是鸭式的;任何强加静态类型的尝试要么失败,要么破坏语言。
  • 标签 static-analysis 暗示这不是在运行时强加的。
  • 我知道这在问题中是隐含的,但我认为在可用时提供正确、惯用的答案更为重要。
猜你喜欢
  • 2020-02-07
  • 1970-01-01
  • 1970-01-01
  • 2011-02-06
  • 2015-07-31
  • 1970-01-01
  • 2012-06-10
  • 2014-03-31
  • 1970-01-01
相关资源
最近更新 更多