Funções como objetos de primeira classe

Quando você começa a ler um pouquinho mais a fundo sobre linguagens de programação em geral, ou Python em específico, é comum encontrar referências dizendo que funções em python são objetos de primeira classe. Mas o que significa isso?

Dizer que funções são objetos de primeira classe em uma linguagem de programação significa que naquela linguagem uma função é um objeto como qualquer outro, podendo ser tratada da mesma forma que os demais objetos. Ou seja, podemos atribuir uma função a uma variável (ou melhor, dar um nome a uma função), passar uma função como parâmetro para outra função, além de outras operações. Como em Python as funções são objetos de primeira classe, vamos ver alguns exemplos:

 def soma(x, y): return x + y
>>> type(soma)
function
>>> s = soma
>>> s(1, 2)
3
>>> soma(1, 2)
3

No exemplo acima, criamos uma função, que nada mais é do que um objeto do tipo function, e inicialmente referenciamos ela pelo nome soma. Como essa função é um objeto como qualquer outro, podemos então criar uma nova referência a ela (s no exemplo acima).

O mais legal de podermos tratar funções assim é que podemos passar funções como argumentos para outras funções. Como exemplo, vamos criar uma função semelhante à função builtin filter. Ela irá receber uma lista de elementos (de qualquer tipo) e uma função que determina se o elemento deve ser incluso na lista de resultados ou não.

def filtra(lista, aceita):
    result = []
    for elemento in lista:
        if aceita(elemento):
            result.append(elemento)
    return result

No exemplo acima, aceita deve ser um objeto do tipo function, que verifique algo em um objeto qualquer e retorne True ou False (ou outros valores que podem ser avaliados como tal). Feito isso, agora vamos usar a função filtra recém definida.

def eh_positivo(valor):
    return valor > 0

lista_de_int = [-10, 10, 2, -7, 3, 5, 1]
nova_lista = filtra(lista_de_int, eh_positivo)
print nova_lista  # imprime [10, 2, 3, 5, 1]

No exemplo acima, passamos à função filtra uma lista de inteiros e uma função apropriada para aceitação de elementos do tipo int. O mais interessante de a função filtra receber uma função como parâmetro é que isso a deixa muito mais flexível, pois ela poderá funcionar para elementos de qualquer tipo e para as mais variadas semânticas de aceitação de valores, desde que seja fornecida uma função apropriada para isso. Abaixo, definimos uma função que aceita strings que contém espaços e rejeita as que não contém.

def tem_espacos(s):
    return ' ' in s

lista_de_str = ["olá mundo", "hello", "testando 123"]
print filtra(lista_de_str, tem_espacos)  # imprime ["olá mundo", "testando 123"]

Existem várias funções prontas que aceitam outras funções como argumentos. Anteriormente, aqui no blog, já vimos map, reduce e filter. Ao ordenar uma lista podemos passar uma função que será usada para comparar os elementos, e existem muitos outros exemplos.

Com a possibilidade de tratar funções como objetos, podemos escrever funções genéricas para lidar com dados independentemente do tipo.

Anúncios

2 comentários sobre “Funções como objetos de primeira classe

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s