Funções, Strings e Exceções

Autor

Douglas Braga

Nota

Esta seção corresponde a Functions, Strings e Exceptions, do capítulo 2 de Grus (2019).

DicaO que esta seção assume

Que você sabe o que é uma função, um parâmetro e uma exceção. O que provavelmente é novo: funções como valores de primeira classe, lambda, argumentos nomeados com padrão, e o estilo pythônico de tratar erro.

Funções são valores

Uma função em Python se define com def:

def double(x):
    """
    Aqui vai a docstring, opcional, que explica o que a função faz.
    Por exemplo, esta função multiplica sua entrada por 2.
    """
    return x * 2

double(21)

Definição 7.1  

42

O que importa aqui não é a sintaxe, e sim que funções em Python são objetos de primeira classe. Dá para atribuí-las a variáveis e passá-las como argumento para outras funções:

def apply_to_one(f):
    """Chama a função f com 1 como argumento"""
    return f(1)

my_double = double            # atribui a função a uma variável
x = apply_to_one(my_double)   # e passa a variável adiante

assert x == 2
x
2

Também dá para criar funções curtas e anônimas com lambda:

y = apply_to_one(lambda x: x + 4)

assert y == 5
y
5
ImportanteOnde lambda aparece

No código do livro, quase sempre nos mesmos dois lugares: como argumento key de uma ordenação, ou para gerar os elementos de uma matriz.

num_friends_by_id.sort(key=lambda id_and_friends: id_and_friends[1])
identity_matrix = make_matrix(n, n, lambda i, j: 1 if i == j else 0)

Você não precisa gostar de lambda. Precisa reconhecê-lo, porque o padrão “passar um pedacinho de comportamento para outra função” atravessa o livro.

Parâmetros podem ter valores padrão, e argumentos podem ser passados pelo nome:

def full_name(first="What's-his-name", last="Something"):
    return first + " " + last

assert full_name("Joel", "Grus")   == "Joel Grus"
assert full_name("Joel")           == "Joel Something"
assert full_name(last="Grus")      == "What's-his-name Grus"

full_name(last="Grus")
"What's-his-name Grus"

A terceira linha é o ponto: full_name(last="Grus") pula o primeiro parâmetro pelo nome. Isso aparece bastante em chamadas com muitos parâmetros opcionais — as de matplotlib, no Capítulo 3, são quase todas assim.

Strings

Aspas simples ou duplas, indiferente. A barra invertida escapa caracteres especiais:

tab_string = "\t"        # representa o caractere de tabulação
assert len(tab_string) == 1

not_tab_string = r"\t"   # string "crua": a barra e o t, literalmente
assert len(not_tab_string) == 2

len(tab_string), len(not_tab_string)
(1, 2)

A string crua (r"...") importa mais do que parece: é o que se usa para expressões regulares, onde a barra invertida tem significado próprio e escapá-la duas vezes fica ilegível.

Para montar strings a partir de valores, use f-strings:

first_name = "Joel"
last_name = "Grus"

f"{first_name} {last_name}"
'Joel Grus'

Existem formas mais antigas de fazer isso — concatenação com +, o operador %, o método .format(). Você vai encontrá-las em código antigo, e elas funcionam.

A f-string é a forma óbvia hoje, no sentido do Zen do Python: uma coisa, um jeito.

Exceções

Quando algo dá errado, Python levanta uma exceção. Sem tratamento, o programa para:

try:
    print(0 / 0)
except ZeroDivisionError:
    print("não se pode dividir por zero")
não se pode dividir por zero

Vale notar uma diferença cultural em relação a linguagens onde exceção é reservada para o excepcional.

Em Python, tratar erro com try/except é comum e idiomático — inclusive em situações previsíveis. O estilo tem até nome: é mais fácil pedir perdão do que permissão. Em vez de checar antes se a chave existe no dicionário, muitas vezes se tenta acessar e se trata o KeyError.

Isso não significa capturar tudo. Capture a exceção específica que você sabe tratar. Um except: pelado engole também os erros que você gostaria de ver.

Esse padrão aparece sempre que linhas malformadas de um arquivo de dados precisam ser puladas sem derrubar o processamento inteiro.

Grus, Joel. 2019. Data Science from Scratch: First Principles with Python. 2nd ed. O’Reilly Media.