Quando um argumento deve ser definido como Nenhum em Python?
O foco da minha pergunta é o design.
Se eu tiver um argumento que pode ser Nonee ele é passado entre várias funções até finalmente ser usado, qual função deve tratá-lo como um argumento padrão?
Por exemplo, suponha o seguinte bloco de código:
def foo(a):
b = # some code block to assign b
return bar(a, b)
def bar(a, b):
c = # some code block to assign c
return baz(a, b, c)
def baz(a, b, c):
return a + b + c
O valor padrão deve ser definido apenas em fooe todas as outras funções devem esperar o argumento como obrigatório (por exemplo, foo(a=None); bar(a, b); baz(a, b, c))? Ou existe um design melhor?
E se a verificação de tipo foi necessária, qual é a função mais adequada para isso?
Respostas
Para tomar uma decisão sensata sobre os argumentos padrão, é preciso saber o contexto de como essas funções serão usadas! .
Se foofor fazer parte da API pública de um módulo ou componente, fornecer um argumento padrão a=Nonepressupõe que haja um cenário de uso frequente em foo()que será chamado neste formato, sem nenhum parâmetro. A mesma medida é válida para bare baz:
essas funções são usadas apenas "internamente"? Então você saberá precisamente se fornecer um argumento padrão irá economizar algum código repetitivo, ou se
bar(a, b)for chamado apenas uma ou duas vezes, talvez apenas dentrofoo, caso em que um argumento padrão não é benéficoou essas funções também fazem parte da API pública? Em seguida, você precisa estimar como será o cenário de uso típico (para o qual você precisa de algum contexto real). Se você deseja fornecer a capacidade de
barser chamado comobar(b="some value"), o fornecimento da assinaturabar(a=none, b)é necessário, independentemente do parâmetro padrão emfoo.
Portanto, para tomar decisões sobre os argumentos padrão, não olhe para o lado da implementação, olhe para o lado do uso!
Com relação à verificação de tipo: não sou um especialista neste tópico em Python, mas acho que se você quiser adicionar anotações de tipo para análise de tipo estático, IMHO fará mais sentido adicioná-las em todos os níveis da cadeia de chamada (pode ser realmente obrigatório para fazer a análise de tipo funcionar). Se a "função mais interna" ( baz) espera apenas argumentos de um certo tipo, você obviamente deve colocar as anotações de tipo lá. Isso, no entanto, implica que fooe barsó funcionará corretamente com argumentos do mesmo tipo, o que significa que para a análise de tipo estático as anotações também são necessárias.