Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inspect params and return types

Is it possible using Python 3 syntax for declaring input parameters and return value types determine those types? Similarly to determining the number of parameters of a function?

def foo(name: str) -> int:
    ....

I would like to get str and int respectively.

like image 339
user2146414 Avatar asked Mar 29 '18 16:03

user2146414


People also ask

How do I find the return type of a function in Python?

type() method returns class type of the argument(object) passed as parameter in Python.

What is inspect stack ()?

inspect. stack() returns a list with frame records. In function whoami() : inspect. stack()[1] is the frame record of the function that calls whoami , like foo() and bar() . The fourth element of the frame record ( inspect.

How do you check parameters of a function in Python?

You can use inspect. getargspec() to see what arguments are accepted, and any default values for keyword arguments. inspect. getargspec() should be considered deprecated in Python 3.


3 Answers

The typing module has a convenience function for that:

>>> import typing
>>> typing.get_type_hints(foo)
{'name': <class 'str'>, 'return': <class 'int'>}

(the documentation)

This is different from foo.__annotations__ in that get_type_hints can resolve forward references and other annotations stored in string, for instance

>>> def foo(name: 'foo') -> 'int':
...     ...
... 
>>> foo.__annotations__
{'name': 'foo', 'return': 'int'}
>>> typing.get_type_hints(foo)
{'name': <function foo at 0x7f4c9cacb268>, 'return': <class 'int'>}

It will be especially useful in Python 4.0, because then all annotations will be stored in string form.

like image 124
vaultah Avatar answered Oct 12 '22 13:10

vaultah


inspect can be used:

>>> def foo(name: str) -> int:
...     return 0
>>> 
>>> import inspect
>>> 
>>> sig = inspect.signature(foo)
>>> [p.annotation for p in sig.parameters.values()]
[<class 'str'>]
>>> sig.return_annotation
<class 'int'>

@vaultah's method looks even more convenient, though.

like image 28
Paul Panzer Avatar answered Oct 12 '22 14:10

Paul Panzer


def foo(name: str) -> int:
    pass

foo.__annotations__
# {'name': <class 'str'>, 'return': <class 'int'>}

foo.__annotations__['return'].__name__
# 'int'
like image 24
Alex Hall Avatar answered Oct 12 '22 12:10

Alex Hall