Generics é um conceito utilizado em linguagens O.O em que podemos definir classes, métodos e interfaces que aceitam tipos de dados como argumento. Assim, não precisamos escrever código para cada tipo de dado.

No exemplo abaixo, sem utilizar generics, temos que declarar duas funções de adição para os tipos de dados int e float.

Exemplo 1
def adicaoInt(a, b): -> int
    return a + b
    
def adicaoFloat(a,b) -> float:
    return a + b


print(adicaoInt(1,1))
print(adicaoFloat(1.4,1.5))
Saída
2
2.9

Como pode ser observado, duas funções foram codificadas para atender a adição de dois valores inteiros e floats. Como consequência, foi necessário a repetição de código do retorno em ambas as funções, por exemplo.

Fazendo um de Generics, podemos reduzir a repetição de código declarando apenas um função para lidar com os dois tipos de dados utilizados nas funções acima.

Usando o tipo Any, podemos abstrair o tipo de dado de retorno de acordo com o tipo de dado manipulado por uma função.

Sintaxe
def nome_funcao(<parametros>) -> any
    #corpo
Exemplo 2
def adicao(a: any, b: any) -> any:
    return a + b

soma = adicao("string1","string2")
print(soma);
soma = adicao(1.2,1.2)
print(soma);
Saída
string1string2
2.4

Na abordagem acima, caso um tipo de dado não suporte o operador (+), um erro será gerado durante a execução. Nesse caso, o tipo deve declarar a sobrecarga do operador.

Para utilizar generics em Python, precisamos utilizar o package typing de acordo com a sintaxe abaixo:

Sintaxe
from typing import TypeVar

Seu uso é feito como abaixo:

Sintaxe
nome_variavel = Type("nome_variavel")

Os tipos de dados passados como argumento como nome_variavel devem substituir os tipos de dado de parâmetros e retorno:

Sintaxe
def nome_funcao( parametro: nome_variavel) -> nome_variavel
    #corpo

O exemplo abaixo demonstra o uso de generics para criar apenas uma função para adição de valores inteiros, float e string/char. A letra T será usada para indicar o uso de generics, pois é uma letra de uso comum entre linguagens O.O.

Exemplo 3
from typing import TypeVar

T = TypeVar("T") 

def adicao(a: T, b: T) -> T :
    return a + b

print(adicao('A','a'))
print(adicao(1,2))
print(adicao(1.2,1.2))
Saída
Aa
3
2.4
1
2.0

Para o uso de generics com coleções como list, podemos informar o tipo de dado genérico, como por exemplo, na busca de um elemento.

No exemplo abaixo, declaramos um parâmetro do tipo List em que seu tipo de dado do elemento foi informado como T como visto no exemplo 3:

Exemplo 4
from typing import TypeVar, List

T = TypeVar('T') #generic

def GetElemento(lista: List[T], idx: int) -> T: #generic aplicado a List
    return lista[idx]

print(GetElemento([1, 2, 3],0)) 
print(GetElemento(['a', 'b', 'c'],0)) 
Saída
A
1
a

Para uso de generics com classes, por exemplo, podemos definir atributos, métodos, parâmetros e retorno utilizando TypeVar.

Exemplo 5
from typing import TypeVar

T = TypeVar("T")

class MinhaClasse:
    def __init__(self, val: T):
        self.atributoGenerico = val 
    
    def GetAtributoGenerico(self) -> T:
        return self.atributoGenerico

#int float str e char
obj1 = MinhaClasse(10)
obj2 = MinhaClasse(1.99)
obj3 = MinhaClasse('MinhaClasse')
obj4 = MinhaClasse('A')

print(obj1.GetAtributoGenerico()) 
print(obj2.GetAtributoGenerico()) 
print(obj3.GetAtributoGenerico()) 
print(obj4.GetAtributoGenerico()) 
Saída
10
1.99
MinhaClasse
A

Generics em classes pode ser aplicado também em interfaces e classes abstratas. Interface e Classe Abstrata podem ser vistos em Python POO: Classe Abstrata e Python POO: Interface.

  1. 11/09/2025 - revisão 1 - Reescrita
  2. 09/06/2025 - versão inicial