Python:类型检查装饰器

dan*_*451 5 python decorator typechecking python-2.7 python-decorators

我构建了一个类型检查装饰器(带包装):

def accepts_func(*types):
    """ 
    top-level decoration, consumes parameters
    """

    def decorator(func):
        """ 
        actual decorator function, consumes the input function
        """

        @wraps(func)
        def check_accepts(*args):
            """ 
            actual wrapper which does some magic type-checking
            """

            # check if length of args matches length of specified types
            assert len(args) == len(types), "{} arguments were passed to func '{}', but only {} " \
                                            "types were passed to decorator '@accepts_func'" \
                .format(len(args), func.__name__, len(types))

            # check types of arguments
            for i, arg, typecheck in izip(range(1, len(args)+1), args, types):
                assert isinstance(arg, typecheck), "type checking: argument #{} was expected to be '{}' but is '{}'" \
                    .format(i, typecheck, type(arg))

            return func(*args)

        return check_accepts

    return decorator
Run Code Online (Sandbox Code Playgroud)

您可以传递任意数量的类型,它会检查传递的参数类型是否与func“硬编码”中的参数类型相匹配@accepts_func(param_type1, param_type2, ...)

@accepts_func(int, str)
sample_func(arg1, arg2):
    ...does something...
Run Code Online (Sandbox Code Playgroud)

到目前为止它没有任何问题。


然而,由于我不是Python“大师”,我想知道我的解决方案是否适合“更大”的项目?

我的解决方案有什么缺点吗?例如,性能问题、边缘情况下未捕获的错误等等?

有没有办法改进我的解决方案?是否存在更好、更“Pythonic”的解决方案?

注意:我不会对项目中的每个函数进行类型检查,只是对我认为真正需要类型安全的函数进行类型检查。该项目在服务器上运行,因此抛出的错误出现在日志中并且对用户不可见。

Pie*_*rre 3

我实际上不鼓励对输入变量进行类型检查。抛开性能不谈,Python 是一种动态类型语言,在某些情况下(例如测试),您需要传递一个对象来实现您最初计划使用的对象的某些属性,并且这将与您的代码配合良好。

一个简单的例子:

class fake_str:
    def __init__(self, string):
        self.string = string

    def __str__(self):
        return self.string

string = fake_str('test')

isinstance(string, str) # False
string # 'test'
Run Code Online (Sandbox Code Playgroud)

你为什么不接受有效的东西?

只需允许兼容的对象与您的代码一起使用即可。

请求原谅比请求许可更容易