# O que é a função type() em Python?

A função `type()` em Python é uma **função básica para a manipulação de tipos**. Como parte da implementação de Python, ela pertence ao núcleo dessa linguagem.

## Para que serve a função `type()` em Python?

A função `type()` em Python é usada em **dois cenários diferentes**:

1. Para obter o tipo de um objeto Python.
2. Para criar dinamicamente uma nova classe.

Vamos considerar **o primeiro caso**, que ocorre com muito mais frequência no uso diário.

### Obter tipo de objeto com `type()`

Python é uma linguagem dinâmica. Isso significa que seus tipos são determinados somente durante o tempo de execução, sendo vinculados a valores em vez de a variáveis. Dessa circunstância surge a necessidade de determinar o **tipo de um objeto no tempo de execução**.

Vamos chamar a função Python `type()` e passar um objeto como o único parâmetro. Em troca, obtemos o tipo do objeto, como `int` ou `str`:

```Python
# O tipo de `42` é `int`
assert type(42) == int
# O tipo de `str(42)` é `str`
assert type(str(42)) == str
```

Se chamarmos a função `type()` no REPL de Python, **a representação textual do objeto retornado mencionará “class” em vez de “type”**:

```Python
# Retorna "<class 'int'>" no REPL
type(42)
```

O que parece confuso a princípio faz todo o sentido, porque, em Python, “tudo é um objeto”. **Em Python, o tipo de um objeto corresponde à classe dele**. Assim, chamar a função `type()` é geralmente equivalente a ler o atributo `__class__`:

```Python
# Deve valer na maioria dos casos
assert type(obj) é obj.__class__
```

### Criar novo tipo com `type()`

Agora, vamos explorar o segundo uso possível da função `type()`. Quando **chamada com três argumentos**, ela nos permite a criação dinâmica de um novo tipo:

```Python
type(name, bases, dict, **kwds)
```

Nessa forma, a função `type()` em Python se comporta de maneira semelhante à palavra-chave `class`. O código `type = type("Type", bases, dict)` pode ser pensado como uma definição de classe equivalente:

```Python
class <Type>(<bases>):
    <dict>
```

Abaixo está um exemplo de uso do **type() em Python para criar novos tipos**. Aqui está uma visão geral dos argumentos:

<table>
  <thead>
    <tr>
      <th>`name`</th>
      <th>`bases`</th>
      <th>`dict`</th>
      <th>`**kwds`</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Nome do novo tipo como string</td>
      <td>Tupla com classes base</td>
      <td>Dicionário com atributos da nova classe</td>
      <td>Argumentos adicionais para instanciação da metaclasse</td>
    </tr>
  </tbody>
</table>

Dica Com o [Deploy Now](https://www.ionos.com/hosting/deploy-now "Deploy Now — IONOS") da IONOS, você pode implantar sites e aplicativos pelo GitHub.

## Como a função `type()` em Python funciona?

Se você usar a função `type()` para determinar o tipo de um objeto, o **valor retornado** não será uma string, mas um **objeto independente**:

```Python
# O valor retornado por `type(42)` não é uma string
assert type(42) != 'int'
# Obtemos um objeto chamado `int`
assert type(42) == int
```

Vamos observar alguns **exemplos de valores retornados pela função `type()`** para objetos de diferentes tipos:

```Python
# Objetos Python de diferentes tipos
diferentes_objs = None, True, 42, 'John', ('Walter', 'White'), ...
# Imprima o tipo de cada objeto
for obj in diferentes_objs:
    print(f"{obj}: {type(obj)}")
```

<table>
  <thead>
    <tr>
      <th>Chamada de `type()`</th>
      <th>Representação textual</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>`type(None)`</td>
      <td>`<class 'NoneType'>`</td>
    </tr>
    <tr>
      <td>`type(True)`</td>
      <td>`<class 'bool'>`</td>
    </tr>
    <tr>
      <td>`type(42)`</td>
      <td>`<class 'int'>`</td>
    </tr>
    <tr>
      <td>`type('John')`</td>
      <td>`<class 'str'>`</td>
    </tr>
    <tr>
      <td>`type(('Walter', 'White'))`</td>
      <td>`<class 'tuple'>`</td>
    </tr>
    <tr>
      <td>`type(...)`</td>
      <td>`<class 'ellipsis'>`</td>
    </tr>
  </tbody>
</table>

Surge então a pergunta: qual é o **tipo do objeto** retornado por `type()`? Vamos tentar descobrir. Chamamos a função Python `type()` e passamos o valor retornado de outra chamada de `type()`:

```Python
# Retorna: "<class 'type'>"
type(type(42))
```

Isso mostra que, além da função `type()` embutida em Python, existe **o tipo `type`, que possui o mesmo nome**. Esse tipo representa todos os outros tipos em Python, conforme ilustrado no exemplo:

```Python
# Objetos Python diferentes
diferentes_objs = None, True, 42, 'John', ('Walter', 'White'), ...
# Verifique o tipo do tipo de cada objeto
for obj in diferentes_objs:
    # Mostre que o tipo do tipo é sempre `type`
    assert type(type(obj)) é type
```

Assim, o tipo de qualquer tipo em Python é `type`. Se isso parece confuso, espere até descobrir que **o tipo do objeto `type` é outro `type`**. Isso pode ser continuado indefinidamente, como uma cobra mordendo o próprio rabo:

```Python
# É `type` o tempo todo
assert type(type(type(type))) é type
```

Para esclarecer qualquer confusão, é essencial que você se aprofunde no sistema de programação orientada a objetos (OOP) de Python. **O objeto embutido `type` em Python representa uma metaclasse**. Uma metaclasse se comporta, em relação a uma classe, como uma classe se comporta em relação a um objeto. Em outras palavras, uma metaclasse funciona como um modelo para uma classe, enquanto uma classe funciona como um modelo para um objeto:

<table>
  <thead>
    <tr>
      <th>Modelo</th>
      <th>Instância</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Classe</td>
      <td>Objeto</td>
    </tr>
    <tr>
      <td>Metaclasse</td>
      <td>Classe</td>
    </tr>
    <tr>
      <td>exemplo: `type`</td>
      <td>`int`, `str`, etc.</td>
    </tr>
    <tr>
      <td>exemplo: `int`</td>
      <td>42</td>
    </tr>
    <tr>
      <td>exemplo: `str`</td>
      <td>“Walter White”</td>
    </tr>
  </tbody>
</table>

## Como usar a função `type()` em Python?

A função `type()` em Python é comumente usada para **recuperar o tipo de um objeto no tempo de execução**. Essa funcionalidade é valiosa, porque o Python é uma linguagem dinamicamente tipada. Em contraste, linguagens estaticamente tipadas, como Java, exigem que os tipos das variáveis sejam declarados, não podendo ser alterados no tempo de execução.

```Java
// Declarar variável como `boolean`
boolean resposta;
// Tentar atribuir valor `int`
// Gera erro de tipo
resposta = 42;
```

Por outro lado, variáveis em Python são simplesmente nomes que se referem a valores tipados. A qualquer momento durante a execução do código, um **nome pode ser referenciado a um valor de tipo diferente**. Portanto, para determinar o tipo de uma variável Python no tempo de execução, você precisa da função `type()`:

```Python
# Atribuir valor booleano
resposta = True
# Mostrar que o tipo é `bool`
assert type(resposta) é bool
# Reatribuir valor inteiro
resposta = 42
# Mostrar que o tipo agora é `int`
assert type(resposta) é int
```

### Verificar tipo de argumento de função com `type()`

Ao definir uma função, muitas vezes é necessário verificar se os **argumentos cumprem certos critérios**. Isso inclui checar se os argumentos estão dentro de certos limites ou confirmar que são de tipos adequados. Ao realizar essas verificações, você pode evitar potenciais erros de tempo de execução.

Vamos ilustrar o uso da função `type()` com um exemplo. Definiremos uma função que soma uma lista de números. Para que ela funcione, precisamos **garantir que cada argumento seja um número**. Para isso, usamos `type()` dentro de uma instrução `assert`:

```Python
# Função para somar argumentos numéricos
def soma_numeros(*args):
  resultado = 0
  # Verificar cada argumento
  for arg in args:
    # Abort com mensagem de erro se o argumento não for `int` ou `float`
    assert type(arg) in (int, float), f"Argumento `{arg}` não é um número"
    # Adicionar o valor do argumento ao total
    resultado += arg
  return resultado
 
# Mostrar que funciona para números
assert soma_numeros(35, 7) == 42
# O seguinte falhará
soma_numeros(29, 'treze')
```

### Depurar com a função `type()` no REPL

Uma das vantagens de linguagens interpretadas, como Python, é a **execução interativa de códigos no REPL** (*Read-Eval-Print-Loop*), que possibilita prototipagem rápida e depuração por meio da inspeção de objetos na memória.

Vamos imaginar o seguinte cenário. Nosso código contém uma variável `resposta`, que deveria conter um valor booleano. Descobrimos que o **tipo não corresponde às nossas expectativas** e usamos a função `type()` em Python para exibir o tipo. Como se constata, escrevemos acidentalmente o valor booleano entre aspas – um erro comum, especialmente entre os iniciantes:

```Python
# Atribuído acidentalmente como string
resposta = 'False'
# A asserção falhará
assert type(resposta) é bool
# Corrigir para valor booleano
resposta = False
# Agora a asserção é válida
assert type(resposta) é bool
```

### Criar classes dinamicamente com a função `type()`

Como já demonstrado, classes em Python podem ser criadas dinamicamente, ou seja, no tempo de execução, pela função `type()`. **Isso é útil, entre outras coisas, em famílias de classes**. Vamos demonstrar o conceito de famílias de classes com um exemplo que usa tags HTML. Primeiramente, criamos uma classe base `Tag`, para que objetos dessa classe possam se representar como código HTML.

```Python
# Classe representando uma tag HTML
class Tag:
    # Inicializar tag HTML com conteúdo
    def __init__(self, *args):
        # Juntar conteúdo da tag
        self.content = "".join([arg.__str__() for arg in args])
    # Representação como string retorna HTML
    def __str__(self):
        return f"<{self.name}>{self.content}</{self.name}>"
```

Para especializar a classe base `Tag`, por herança, para tags HTML específicas, como `<p>` e `<h1>`, podemos utilizar novamente a função `type()`. Vamos ilustrar a situação com um exemplo:

```Python
# Criar classe `P`
P = type('P', (Tag,), {"name": 'p'})
```

1. Nome da nova classe como string.
2. Tupla com classes base.Python permite heranças múltiplas; para derivação de apenas uma classe, usamos a notação `(NomeClasse,)`.
3. Dicionário com o nome da classe e as entradas adicionais, se necessário. Essas entradas também podem ser funções. Posteriormente, **instanciamos uma tag `p`** e verificamos se a representação funciona corretamente:

```Python
# Instanciar tag `p`
cumprimento = P("Olá, mundo")
assert str(cumprimento) == '&lt;p&gt;Olá, mundo&lt;/p&gt;'
```

O mesmo efeito pode ser alcançado por **definição de classe análoga**:

```Python
# Criar classe `P`
class P(Tag):
    name = 'p'
```

Como no outro exemplo, criamos classes para títulos usando `type()`. Fazendo uso da capacidade de criação dinâmica de classes com `type()`, podemos **criar classes para todos os seis níveis de títulos, de uma só vez, usando a compreensão de listas**:

```Python
h_1_a_6 = (f"h{n}" for n in range(1, 7))
titulos = [type(titulo, (Tag,), {"name": titulo}) for titulo in h_1_a_6]
```

Como você pode ver, vale a pena usar a função `type()` para **criar várias subclasses relacionadas**. Demonstramos essa abordagem usando o exemplo mais complexo de definição de classes para modelar cartas de baralho. Primeiramente, definimos uma superclasse, `Carta`, usando a palavra-chave `class`:

```Python
# Classe representando carta de baralho abstrata
class Carta:
    def __init__(self, numero):
        self.numero = numero
    # Representação como string
    def __str__(self):
        return f"{self.numero} de {self.naipes}"
```

Em seguida, **criamos subclasses para os quatro naipes** usando `type()`:

```Python
# Criar tipos concretos para cada naipe
Paus = type('Paus', (Carta,), {'naipe': 'Paus'})
Ouros = type('Ouros', (Carta,), {'naipe': 'Ouros'})
Copas = type('Copas', (Carta,), {'naipe': 'Copas'})
Espadas = type('Espadas', (Carta,), {'naipe': 'Espadas'})
```

Agora, as **cartas individuais podem ser instanciadas**:

```Python
# Instanciar um 7 de Espadas
carta = Espadas(7)
# Mostrar que funcionou
assert str(carta) == '7 de Espadas'
```

## Quais são os limites da função `type()`?

A função `type()` em Python é útil, mas em alguns casos ela pode **atingir seu limite**. Felizmente, para essas situações, a linguagem oferece algumas soluções alternativas. Vamos analisá-las.

### Quebrar hierarquias de herança com `isinstance()`

`type()` somente determina o tipo real de um objeto em Python, ignorando a hierarquia de herança. Vamos ilustrar esse dilema reutilizando o nosso exemplo de cartas de baralho. **O tipo da carta 7 de espadas deveria ser tanto “carta de baralho” quanto “espadas”**. No entanto, com `type()`, isso não ocorre:

```Python
# Criar Sete de Espadas
carta = Espadas(7)
# Nossa carta é uma Espada, certo
assert type(carta) é Espadas
# Mas não é uma carta??
assert type(carta) não é Carta
```

Para quebrar corretamente o **polimorfismo subjacente**, temos de usar a função `isinstance()`.

```Python
# Sete de Espadas é `Espadas`
assert isinstance(carta, Espadas)
# E também é uma `Carta`
assert isinstance(carta, Carta)
```

### Simplificar detecção de tipo de objetos com `match-case`

Como já demonstrado, a função `type()` é frequentemente usada para determinar o tipo de um objeto no tempo de execução. Para distinguir **vários tipos possíveis entre si**, uma estrutura `if-elif-else` deve ser usada:

```Python
# Determinar o tipo do objeto
if type(obj) é int:
    print("Int")
elif type(obj) é float:
    print("Float")
elif type(obj) é ...:
    print("...")
else:
    print("Algo diferente")
```

A partir da versão Python 3.10, no entanto, a instrução `match-case` é suportada. Ela é capaz de **reconhecer tipos sem chamar a função `type()`**.

Em um bloco `case`, funções construtoras como `int(obj)` ou `str(obj)` podem ser usadas para fazer o bloco corresponder (*match*), se o objeto tiver o respectivo tipo.

```Python
# Exemplo de objeto
obj = 42
# Determinar tipo de objeto
match obj:
    case int(obj):
        print(f"{obj} é `int`")
    case float(obj):
        print(f"{obj} é `float`")
    case _:
        print(f"{obj} é outra coisa")
```

Dica Se você está começando agora nessa linguagem de programação, acesse o nosso [tutorial sobre Python](https://www.ionos.com/pt-br/digitalguide/sites-de-internet/desenvolvimento-web/aprender-python/). Nosso artigo sobre [operadores em Python](https://www.ionos.com/pt-br/digitalguide/sites-de-internet/desenvolvimento-web/operadores-python/) também pode lhe ser útil.


This is a markdown version of: [https://www.ionos.com/pt-br/digitalguide/sites-de-internet/desenvolvimento-web/funcao-type-em-python/](https://www.ionos.com/pt-br/digitalguide/sites-de-internet/desenvolvimento-web/funcao-type-em-python/) for AI/LLM consumption.