检查函数参数类型是 Pythonic 吗? [英] Is it Pythonic to check function argument types?

查看:40
本文介绍了检查函数参数类型是 Pythonic 吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道,在 Python 中通常不赞成类型检查函数参数,但我认为我已经提出了一种这样做的情况.

I know, type checking function arguments is generally frowned upon in Python, but I think I've come up with a situation where it makes sense to do so.

在我的项目中,我有一个抽象基类 Coord,带有一个子类 Vector,它具有更多功能,如旋转、改变幅度等.数字列表和元组也将为 isinstance(x, Coord) 返回 True. 我还有许多函数和方法接受这些 Coord 类型作为参数.我已经设置了装饰器来检查这些方法的参数.这是一个简化版本:

In my project I have an Abstract Base Class Coord, with a subclass Vector, which has more features like rotation, changing magnitude, etc. Lists and tuples of numbers will also return True for isinstance(x, Coord). I also have many functions and methods that accept these Coord types as arguments. I've set up decorators to check the arguments of these methods. Here is a simplified version:

class accepts(object):
    def __init__(self, *types):
        self.types = types

    def __call__(self, func):
        def wrapper(*args):
            for i in len(args):
                if not isinstance(args[i], self.types[i]):
                    raise TypeError

            return func(*args)

        return wrapper

这个版本很简单,还是有一些bug.它只是为了说明这一点.它会像这样使用:

This version is very simple, it still has some bugs. It's just there to illustrate the point. And it would be used like:

@accepts(numbers.Number, numbers.Number)
def add(x, y):
    return x + y

注意:我只是根据抽象基类检查参数类型.

Note: I'm only checking argument types against Abstract Base Classes.

这是个好主意吗?有没有更好的方法来做到这一点,而不必在每种方法中重复类似的代码?

Is this a good idea? Is there a better way to do it without having to repeat similar code in every method?

如果我做同样的事情,但不是在装饰器中预先检查类型,而是在装饰器中捕获异常怎么办:

What if I were to do the same thing, but instead of checking the types beforehand in the decorator, I catch the exceptions in the decorator:

class accepts(object):
    def __init__(self, *types):
        self.types = types

    def __call__(self, func):
        def wrapper(*args):

            try:
                return func(*args)
            except TypeError:
                raise TypeError, message
            except AttributeError:
                raise AttributeError, message

        return wrapper

这样更好吗?

推荐答案

您的品味可能会有所不同,但 Pythonic(tm) 风格是继续前进并根据需要使用对象.如果它们不支持您尝试的操作,则会引发异常.这称为鸭子打字.

Your taste may vary, but the Pythonic(tm) style is to just go ahead and use objects as you need to. If they don't support the operations you're attempting, an exception will be raised. This is known as duck typing.

支持这种风格有几个原因:首先,只要新对象支持正确的操作,它就允许您在现有代码中使用新类型的对象,从而实现多态性.其次,它避免了大量检查,从而简化了成功路径.

There are a few reasons for favoring this style: first, it enables polymorphism by allowing you to use new kinds of objects with existing code so long as the new objects support the right operations. Second, it streamlines the successful path by avoiding numerous checks.

当然,使用错误参数时您得到的错误信息通过类型检查比使用鸭子类型检查更清晰,但正如我所说,您的品味可能会有所不同.

Of course, the error message you get when using wrong arguments will be clearer with type checking than with duck typing, but as I say, your taste may vary.

这篇关于检查函数参数类型是 Pythonic 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆