Python 简单的动态类型检查

Python 简单的动态类型检查,python,Python,是否有一种“标准”方法可以在Python中添加简单的动态类型检查,例如: def add(a, b): # Argument type check check(a, int) check(b, int) # Calculate res = a + b # Result type check and return check(res, int) return res 如果类型不匹配,则可通过检查引发异常 我当然可以自己做一些东西,

是否有一种“标准”方法可以在Python中添加简单的动态类型检查,例如:

def add(a, b):
    # Argument type check
    check(a, int)
    check(b, int)
    # Calculate
    res = a + b
    # Result type check and return 
    check(res, int)
    return res
如果类型不匹配,则可通过检查引发异常

我当然可以自己做一些东西,做
isinstance(…,…)
type(…)==…
,但我想知道是否有一些“标准”模块用于这种类型的检查

如果还可以进行更复杂的类型检查,比如检查参数是
str
还是
int
,或者是
str
列表,那就更好了

我知道它在某种程度上违背了Pythons的duck类型原则,但由于一个类型错误的参数,我只花了几个小时进行调试,这是一个大型程序,因此原因显示了许多嵌套调用。

在进入Python时,通常会考虑使用它,你想怎么做就怎么做

您的代码不应该依赖于具体类型,而应该依赖于通用接口(例如,不是两个东西是否是整数,而是它们是否“可添加”)。这允许您利用动态类型和编写通用函数。如果一个类型不能处理您想要的接口,它将抛出一个您可以捕获的异常。所以,你的加法最好是这样做

def add(a, b):
  try:
    return a + b
  except TypeError as t:
    # some logging code here for your debugging ease
    raise t
如果您使用的是Python3,那么函数有可选的类型注释。这意味着以下代码是有效的Python3

def add(a:int, b:int):
   return a + b

我不知道是否有任何工具可以利用这些提示为您提供实际的编译时检查。

您可以使用decorator函数。大概是这样的:

def typecheck(*types):
    def __f(f):
        def _f(*args):
            for a, t in zip(args, types):
                if not isinstance(a, t):
                    print "WARNING: Expected", t, "got", a
            return f(*args)
        return _f
    return __f

@typecheck(int, str, int)
def foo(a, b, c):
    pass    

foo(1, "bar", 5)
foo(4, None, "string")
输出(第二次调用)为

警告:应为,未获得
警告:应为,得到“字符串”
但就目前情况而言,这不适用于关键字参数


编辑:在谷歌搜索之后,我发现一些更复杂的类型检查装饰程序也支持关键字参数和返回类型。

?是的,这是一种可能性,但我想知道是否有一些已经为此让路了;更新了这个问题,谢谢。请参阅MyPy项目,了解Python的可选静态类型:您还可以查看。除了您提到的非Python之外,“动态类型检查”听起来像是一个可能的矛盾修饰法。您的代码看起来不是很动态,也许一些位置良好的
assert
语句可以防止您遇到问题。我刚刚在Python 3.4.1上尝试了
def add(a:list,b:tuple):
,但它没有使用提示,因此
add(2,2)
根据annotation.Yes运行时,对明显错误的类型没有任何注释。我就是这么说的。解释器将信息存储在
add.\uuuuuu annotations\uuuu
中,因此任何工具都可以使用这些信息来验证调用。例如,您可以编写一个
@exforce_types
装饰器,以确保其他内容不会被传递。但编译器本身并没有这样做。引述如下:“Python本身并没有给注释附加任何特定的含义或意义……注释具有意义的唯一方式是当它们被第三方库解释时。”。如果使用mypy,则执行的是静态类型检查,而不是动态类型检查。只是添加了一条注释。:)使用decorator的想法很有趣,感谢您提供其他工作的链接。
WARNING: Expected <type 'str'>, got None 
WARNING: Expected <type 'int'>, got 'string'