How to set default in parameters when specifying the type of the object?

Asked

Viewed 217 times

4

When defining functions, I usually use the feature of specifying the type of object that can be used as argument and which object the function should return. See example below:

def count_elements(lista_a: list, lista_b:list)->int:
    result = len(lista_a)+len(lista_b)
    return result

count_elements([1,2,3],[4,5,6])

Output:

6

It happens that when I try to establish default values, python returns the message invalid syntax. I tried that way, unsuccessfully:

def count_elements(lista_a: list, lista_b = [1,2,3]:list)->int:
    result = len(lista_a)+len(lista_b)
    return result

It is possible to establish argument default and specify the type of object at the same time?

1 answer

3


The order of the Annotation (the type marking) and the default values is contrary to what you are trying to do: first the parameter name, the sign of :, the note, and then the sign of = followed by the default value:

def count_elements(lista_a: list, lista_b: list = [1,2,3])->int:
    result = len(lista_a)+len(lista_b)
    return result

This code has another error, this time much more subtle, so I take this opportunity to comment: never whether to put a list, or another mutable object as the default value of a parameter.

This is because the objects used as default value are created only once, when the function is created, and re-used in all the calls that function - then if the function changes the list, in a second call to the function, the list appears changed:

# exemplo do problema no terminal interativo: 

>>> def aumenta_lista(lista=[]):
...     lista.append(len(lista))
...     return lista
... 
>>> aumenta_lista()
[0]
>>> aumenta_lista()
[0, 1]
>>> aumenta_lista()
[0, 1, 2]

The correct in these cases is to use None to dismiss who calls the function of sending the parameter, and create the list within the function, using a if:

def count_elements(lista_a: list, lista_b: list=None)->int:
    if lista_b is None:
        lista_b = [1, 2, 3]
    result = len(lista_a)+len(lista_b)
    return result

This ensures that the lista_b will be created within the function each time it is called. BUT see, that now the default parameter is a None, It’s not a list! So, for typing to be correct in these cases, and to be approved by verification tools, it is necessary to say that this parameter has to be EITHER a list OR a None.

The module typing standard library has the class Optional for these cases - the correct then is so:

import typing as T


def count_elements(lista_a: list, lista_b: T.Optional[list] = None)->int:
    if lista_b is None:
        lista_b = [1, 2, 3]
    result = len(lista_a)+len(lista_b)
    return result

(The Typing module has several classes that are made to be used with the syntax of [ ], to detail more about the type annotation - it is worth seeing the documentation of how it is used)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.