在Python中检查函数/方法中参数的类型

在Python中检查函数/方法中参数的类型,python,exception,types,arguments,Python,Exception,Types,Arguments,在Python中,我想检查传递给函数的参数的类型 我编写了两个实现: class FooFloat(float): pass # Solution 1 def foo(foo_instance): if type(foo_instance) is FooFloat: raise TypeError, 'foo only accept FooFloat input' # Solution 2 def foo(foo_instance): assert type

在Python中,我想检查传递给函数的参数的类型

我编写了两个实现:

class FooFloat(float):
    pass

# Solution 1
def foo(foo_instance):
   if type(foo_instance) is FooFloat:
      raise TypeError, 'foo only accept FooFloat input'


# Solution 2
def foo(foo_instance):
   assert type(foo_instance) is FooFloat, 'foo only accept FooFloat input'
在我看来,后者更容易阅读,而且不太繁琐。但是,它将抛出一个
AssertionError
,这不是我想提出的错误类型

在这种情况下,是否有更好的第三种解决方案更常见

我在想一个装饰师:

@argtype('foo_instance', FooFloat)
def foo(foo_instance):
   pass

我喜欢这个想法,并考虑将来使用它。我实现了第三个解决方案,如下所示,请尝试一下

def argtype(arg_name, arg_type):
    def wrap_func(func):
        def wrap_args(*args, **kwargs):
            if not isinstance(kwargs.get(arg_name), arg_type):
                raise TypeError, '%s\'s argument %s should be %s type' % (func.__name__, arg_name, arg_type.__name__)
            return func(*args, **kwargs)
        return wrap_args
    return wrap_func


@argtype('bar', int)
@argtype('foo', int)
def work(foo, bar):
    print 'hello word'

work(foo='a', bar=1)
此外,如果有继承,我认为使用isinstance更合适

这样做。它接受类型和子类型

if not isinstance(arg,<required type>):
    raise TypeError("arg: expected `%s', got `%s'"%(<required type>,type(arg))

也要考虑显式类型检查(这包括检查特殊成员,例如:代码>迭代器)。完整的“duck typing vs type checks”讨论超出了当前主题的范围,但是,与简单和通用的接口相比,显式检查似乎更适合高度专业化和/或复杂的接口。

Python 3.5中可能存在重复的类型提示功能:@eph:但它不进行任何检查。@user2357112:Python鼓励检查attr而不是类型。但您仍然可以像在mypy中一样使用装饰程序进行类型检查
(n,t)=('arg',<required_type>);o=locals()[n]
if not isinstance(o,t):
    raise TypeError("%(n)s: expected `%(t)s', got `%(rt)s'"
            %dict(locals(),rt=type(o)) # fine in this particular case.
                                       # See http://stackoverflow.com/a/26853961/648265
                                       # for other ways and limitations
del n,t,o
assert isinstance(arg,<type>),"expected `%s',got `%s'"%(<type>,type(arg))
        #arg name would be seen in the source in stacktrace