可能重复:
Python 中用于静态类型检查的工具
在大多数情况下,我喜欢这样一个事实,即您可以在 Python 中选择任何类型并将其放在您喜欢的位置,然后让 Duck 类型接管。但是如何阻止该死的事情通过编译时间。有没有办法在编译时需要时强制执行某种健全性检查,而无需求助于 Unit Tesing。
可能重复:
Python 中用于静态类型检查的工具
在大多数情况下,我喜欢这样一个事实,即您可以在 Python 中选择任何类型并将其放在您喜欢的位置,然后让 Duck 类型接管。但是如何阻止该死的事情通过编译时间。有没有办法在编译时需要时强制执行某种健全性检查,而无需求助于 Unit Tesing。
使用像Pychecker这样的单独工具来警告您诸如使用不存在的方法或属性之类的事情。这不是编译的一部分,但您可以将其作为您自己进程的一部分强制执行,例如 VCS 中的预提交挂钩。
不,Python 编译器甚至不知道(通常也不知道)你是否正确拼写了变量名,更不用说每个变量、对象属性、集合槽等中可能包含的类型。这不仅仅是因为编写它的人有其他优先事项,大多数代码很难甚至不可能。对于一些非常简单的情况,静态分析器可能会尝试这样的事情。但实际上,这是不可能的。
Python 并没有其他静态语言所具有的明确定义的“编译时间”。
但是,您可以使用isinstance()
andtype()
来验证您的对象是否是您期望的类的实例。
您可以使所有内容的第一行类似于:
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/中编写代码。
Python 没有类似的东西,因为编译是初始化时间。您可以使用assert
语句来强制将特定类型传递给您的函数,即assert type(foo) == list
,但这有点不合 Python,因为它首先破坏了鸭子类型的意义。pythonic 是检查以确保您获得的对象具有您需要的方法。例如,如果您需要遍历对象,请尝试以下操作:
assert '__iter__' in dir(obj)
您可以滥用装饰器,在调试模式下为异常类型添加警告:
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 并且可以利用注释,以防万一它变得非常简单。
我想你只是想要一个快速的类型检查,对吧?
我将通过一个快速演示来回答:
>>> 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
>>>
希望这是有道理的。