10 de dezembro de 2015

Atalhos para and e or

A seguinte construção é bastante comum em Python:
def dividir(a=None, b=None):
    if not a:
        a = 0
    if not b:
        b = 1
    return a / b

Ela usa a avaliação booleana que eu explico no post Comparações em Python. Os testes retornam False se a variável não for informada porque, nesse caso ela assume o conteúdo default: None. Ou se for informado algum valor que seja avaliado como False.

Existe outra forma de fazer a mesma coisa, que talvez você já tenha visto:
def dividir(a=None, b=None):
    a = a or 0
    b = b or 1
    return a / b

Esse último exemplo faz a mesma coisa do primeiro, de uma forma resumida. A lógica por trás é a seguinte:
  1. Se a tiver algum valor que seja avaliado como True faz a = a.
  2. Caso contrário, se a tiver algum valor que seja avaliado como False faz a = 0.
O mesmo princípio se aplica ao teste da variável b.

Existem outras aplicações para essa estrutura:
>>> def a_ou_b(a=None, b=None):
...     if a:
...         return a
...     if b:
...         return b
... 
>>> print (a_ou_b(1, 2))
1
>>> print (a_ou_b(b=2))
2
>>>

Agora, a mesma coisa usando o atalho:
>>> def a_ou_b(a=None, b=None):
...     return a or b
... 
>>> print (a_ou_b(1, 2))
1
>>> print (a_ou_b(b=2))
2
>>>

Existe o mesmo atalho para o and:
>>> a = 0
>>> b = 2
>>> a and b
0
>>> a = 1
>>> a and b
2

Essa lógica é:
  1. Se a tiver algum valor que seja avaliado como False, retorna o valor do próprio a.
  2. Caso contrário, se a tiver algum valor que seja avaliado como True, retorna o valor de b.

Eu uso bastante esses short circuits para testar parâmetros de uma função ou em scripts rápidos e descartáveis, mas não uso em lógicas mais complexas, porque pode confundir quem for dar manutenção no meu código.

Não se esqueça:
Explicit is better than implicit.

Eu sou Vinicius Assef, um programador do século passado que gosta de Python, pratica Lean Development e acredita em Deus. Você pode me contactar por email ou twitter.

Nenhum comentário:

Postar um comentário

Marcadores