Is it possible to make python throw errors if the

2019-04-23 02:33发布

问题:

One of the new features in python3.5 is type hinting. For example the code below is valid now:

def greeting(name: str) -> str:
    return 'Hello ' + name

But, as I understand, it doesn't check anything by itself and also is interpreted absolutely the same way as this:

def greeting(name):
    return 'Hello ' + name

and was implemented mostly to help static analyzers (and to make code that is easier to understand). But is there (or is planned to be implemented in the future) any way (maybe by using some third-party libraries) to make python throw errors when an argument of an invalid type is passed to a function with annotated argument types (using only type-hinting syntax)?

回答1:

Type hints implement PEP 0484 which explicitly lists as a non-goal:

While the proposed typing module will contain some building blocks for runtime type checking -- in particular the get_type_hints() function -- third party packages would have to be developed to implement specific runtime type checking functionality, for example using decorators or metaclasses. Using type hints for performance optimizations is left as an exercise for the reader.

From this it seems to follow that the Python developers have no plan to add the functionality that you seek. The quote mentions decorators and that does seem the way to go. In concept it seems straightforward -- the decorator would use get_type_hints() on the function to be decorated and would iterate through the arguments, checking their types against any hints, either throwing an error if there is a clash or simply passing on the arguments to the function. This would be similar to pzelasko's answer but with the decorator using the hints to automatically handle the boiler-plate code. The simplest approach would be to simply vet the arguments, though you should also be able to make a decorator which would raise an error if the return type clashes with the hint. I don't yet have Python 3.5 and don't have the time to pursue it -- but it seems like a good learning exercise for someone who wants to learn about both decorators and type hints. Perhaps you can be one of the "third parties" the PEP alludes to.



回答2:

I think the simplest way is to check the type:

def greeting(name):
    if type(name) is not str:
        raise TypeError('Expected str; got %s' % type(name).__name__)
    return 'Hello ' + name