可能是重复问题:
Python中用于静态类型检查的工具
大多数情况下,我喜欢在Python中随心所欲地选择任何类型并将其放置到您想要的位置,然后让Duck typing接管。但是如何阻止该方法在编译时通过呢?是否有一种方法可以在需要时强制执行某种合理性检查,而无需使用Unit Tesing。
可能是重复问题:
Python中用于静态类型检查的工具
大多数情况下,我喜欢在Python中随心所欲地选择任何类型并将其放置到您想要的位置,然后让Duck typing接管。但是如何阻止该方法在编译时通过呢?是否有一种方法可以在需要时强制执行某种合理性检查,而无需使用Unit Tesing。
使用类似于Pychecker的独立工具来警告您存在不存在方法或属性的用法。这不是编译的一部分,但您可以将其作为自己流程的一部分强制执行,例如在您的版本控制系统中的预提交钩子。
不行。Python编译器甚至不知道你是否正确拼写变量名,更不用说每个变量、对象属性、集合插槽等中可能出现的类型了。这并不仅仅是因为编写人员有其他优先事项,而是对于大多数代码来说非常困难甚至不可能。对于一些非常简单的情况,静态分析器可能能尝试类似的操作。但实际上,这是不可能的。
Python实际上没有像其他静态语言那样明确定义的"编译时"。
但你可以使用isinstance()
和type()
来验证你的对象是否是你期望的类的实例。
你可以让每个东西的第一行都类似于:
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/ 编写您的代码。
object
)。 - user395760int
和float
等部分只是从某些Python对象隐式转换而来的C值,并且非常有限。你必须编写自己的扩展类型,这只是过度设计和不必要的困难。 - user395760list
或set
类型,只有object
类型。 - user395760Python没有像那样的东西,因为编译是初始化时间。您可以使用assert
语句来强制执行将特定类型传递给函数,例如assert type(foo) == list
,但这有点不符合Python的风格,因为它首先违背了鸭子类型的原则。Pythonic的做法是检查获取到的对象是否具有所需的方法。例如,如果需要对对象进行迭代,请尝试以下操作:
assert '__iter__' in dir(obj)
python -O
,断言会自动禁用。 - Colin Valliant您可以利用装饰器,在调试模式下添加有关异常类型的警告:
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
对于关键字参数的扩展在一般情况下并不容易,除非你使用 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
>>>
希望这有意义。