The function annotations refer to syntax parameters with an expression.
def my_function(x: expression, y: expression = 5):
...
For example:>>> def show(myvar:np.float64):
... print(type(myvar))
... print(myvar)
...
>>> show(1.1)
1.1
>>> def files(filename: str, dot='.') -> list:
... print(filename)
... print(type(filename))
...
>>> files('file.txt')
file.txt
>>> print(files.__annotations__)
{'filename': , 'return': }
>>> print(show.__annotations__)
{'myvar': }
...
You can see the annotation syntax with a dictionary called __annotations__ as an attribute on your functions.This lets you rewrite Python 3 code with function annotations to be compatible with both Python 3 and Python 2.
Type hints are a specialization of function annotations, and they can also work side by side with other function annotations.
Annotations have no standard meaning or semantics.
There are several benefits to the annotations:
- if you rename an argument, the documentation docstring version may be out of date and is easier to see if an argument is not documented;
- is no need to come up with a special format of argument because the annotations attribute provides a direct, standard mechanism of access;
>>> Temperature = float
>>> def forecast(local_temperature: Temperature) -> str:
... print(local_temperature)
...
>>> forecast(13.1)
13.1
...
I can create multiple annotations:
>>> def div(a: dict(type=float, help='the dividend'), b: dict(type=float, help='this <> 0)') ) ->
dict(type=float, help='the result of dividing a by b'):
... return a / b
...
>>> div(3,4)
0.75
...
Annotations for excess parameters like *args and **kwargs, allow arbitrary number of arguments to be passed in a function call.See example with my_func:
def my_func(*args: expression, *kwargs: expression):
...
Annotations combine well with decorators to provide input to a decorator, and decorator-generated wrappers are a good place to put code that gives meaning to annotations, but this is another issue.