Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
269 views
in Technique[技术] by (71.8m points)

python - Is it Pythonic to check function argument types?

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.

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

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?

Edit:

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

Is that any better?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...