5

可能重复:
Python 中用于静态类型检查的工具

在大多数情况下,我喜欢这样一个事实,即您可以在 Python 中选择任何类型并将其放在您喜欢的位置,然后让 Duck 类型接管。但是如何阻止该死的事情通过编译时间。有没有办法在编译时需要时强制执行某种健全性检查,而无需求助于 Unit Tesing。

4

8 回答 8

4

使用像Pychecker这样的单独工具来警告您诸如使用不存在的方法或属性之类的事情。这不是编译的一部分,但您可以将其作为您自己进程的一部分强制执行,例如 VCS 中的预提交挂钩。

于 2011-07-27T20:49:12.743 回答
3

不,Python 编译器甚至不知道(通常也不知道)你是否正确拼写了变量名,更不用说每个变量、对象属性、集合槽等中可能包含的类型。这不仅仅是因为编写它的人有其他优先事项,大多数代码很难甚至不可能。对于一些非常简单的情况,静态分析器可能会尝试这样的事情。但实际上,这是不可能的。

于 2011-07-27T20:48:44.450 回答
3

编译器在 Python 中没有类型信息;但是,例如,可以在语言中添加可选注释,从而为编译器提供已经讨论过的信息

同时,我建议研究PyChecker,它可能会做一些你想做的事情。

于 2011-07-27T20:51:40.273 回答
1

Python 并没有其他静态语言所具有的明确定义的“编译时间”。

但是,您可以使用isinstance()andtype()来验证您的对象是否是您期望的类的实例。

于 2011-07-27T20:48:56.240 回答
1

您可以使所有内容的第一行类似于:

if not all(isinstance(a, b) for a, b in zip(((x, int), (y, str), (z, float))))

您可以使用像http://code.enthought.com/projects/traits/这样的包,它允许您显式声明类型。

您可以在http://cython.org/中编写代码。

于 2011-07-27T20:49:19.193 回答
1

Python 没有类似的东西,因为编译是初始化时间。您可以使用assert语句来强制将特定类型传递给您的函数,即assert type(foo) == list,但这有点不合 Python,因为它首先破坏了鸭子类型的意义。pythonic 是检查以确保您获得的对象具有您需要的方法。例如,如果您需要遍历对象,请尝试以下操作:

assert '__iter__' in dir(obj)
于 2011-07-27T20:49:57.993 回答
1

您可以滥用装饰器,在调试模式下为异常类型添加警告:

import warnings
import functools
import numbers

debug = True

class TypeWarning(Warning):
    pass

def warn_types(*pos_types):
    def decorator(func):
        if not debug:
            return func
        @functools.wraps(func)
        def wrapper(*args):
            for i, (x, t) in enumerate(zip(args, pos_types)):
                if not isinstance(x, t):
                    warnings.warn("Expected %s got %s for argument %d of %s"
                                        % (t.__name__, x.__class__.__name__,
                                           i, func.__name__),
                                  category=TypeWarning, stacklevel=2)
            return func(*args)
        return wrapper
    return decorator


@warn_types(numbers.Number, numbers.Number)
def add(x, y):
    return x + y

这会在不破坏功能的情况下向程序员发出警告,并且可以通过关闭调试模式来关闭它们。在您完成项目编码后,它们也可以通过简单的搜索替换来删除。

>>> print add(3, 4)
7
>>> print add("a", "b")
__main__:1: TypeWarning: Expected Number got str for argument 0 of add
__main__:1: TypeWarning: Expected Number got str for argument 1 of add
ab

在一般情况下,为关键字参数扩展 this 并非易事,除非您使用的是 Python 3 并且可以利用注释,以防万一它变得非常简单。

于 2011-07-27T21:32:20.503 回答
0

我想你只是想要一个快速的类型检查,对吧?

我将通过一个快速演示来回答:

>>> m = 7
>>> m.__class__
<type 'int'>
>>> n = 6
>>> o = 6.6
>>> m.__class__ == n.__class__
True
>>> m.__class__ == o.__class__
False
>>> isinstance(o, int)
False
>>> isinstance(m, int)
True
>>> 

希望这是有道理的。

于 2011-07-27T20:49:30.897 回答