tipo(), isinstância() para obter e determinar o tipo em Python

O negócio

Em Python, as funções integradas tipo() e isinstância() são utilizadas para obter e verificar o tipo de um objecto, tal como uma variável, e para determinar se é de um tipo particular.

O conteúdo seguinte é explicado aqui, juntamente com o código da amostra.

  • Obter e verificar o tipo de objecto:type()
  • Determinação do tipo de objecto:type(),isinstance()
    • Determinação do tipo usando o tipo()
    • Determinação do tipo utilizando isinstância()
    • Diferença entre tipo() e isinstância()

Em vez de determinar o tipo de um objecto, pode-se usar o tratamento de excepções ou a função hasattr() integrada para determinar se um objecto tem os métodos e atributos correctos.

Obter e verificar o tipo de objecto: tipo()

tipo(objecto) é uma função que devolve o tipo do objecto passado como argumento. Isto pode ser utilizado para descobrir o tipo de um objecto.

print(type('string'))
# <class 'str'>

print(type(100))
# <class 'int'>

print(type([0, 1, 2]))
# <class 'list'>

O valor de retorno de tipo() é um objecto de tipo tal como str ou int.

print(type(type('string')))
# <class 'type'>

print(type(str))
# <class 'type'>

Determinação do tipo de objecto: type(), isinstance()

Usar tipo() ou isinstância() para determinar o tipo.

Determinação do tipo usando o tipo()

Comparando o valor de retorno do tipo() com um tipo arbitrário, é possível determinar se o objecto é de qualquer tipo.

print(type('string') is str)
# True

print(type('string') is int)
# False
def is_str(v):
    return type(v) is str

print(is_str('string'))
# True

print(is_str(100))
# False

print(is_str([0, 1, 2]))
# False

Se quiser determinar se é um de vários tipos, utilize o em operador e um tuple ou lista de vários tipos.

def is_str_or_int(v):
    return type(v) in (str, int)

print(is_str_or_int('string'))
# True

print(is_str_or_int(100))
# True

print(is_str_or_int([0, 1, 2]))
# False

Também é possível definir funções que alteram o processamento em função do tipo de argumento.

def type_condition(v):
    if type(v) is str:
        print('type is str')
    elif type(v) is int:
        print('type is int')
    else:
        print('type is not str or int')

type_condition('string')
# type is str

type_condition(100)
# type is int

type_condition([0, 1, 2])
# type is not str or int

Determinação do tipo utilizando isinstância()

isinstância(objecto, classe) é uma função que retorna verdadeiro se o objecto do primeiro argumento for uma instância do tipo ou subclasse do segundo argumento.

O segundo argumento pode ser um tuple de tipos. Se for uma instância de qualquer dos tipos, a verdade é devolvida.

print(isinstance('string', str))
# True

print(isinstance(100, str))
# False

print(isinstance(100, (int, str)))
# True

Uma função semelhante ao exemplo de determinação do tipo utilizando o tipo() pode ser escrita da seguinte forma

def is_str(v):
    return isinstance(v, str)

print(is_str('string'))
# True

print(is_str(100))
# False

print(is_str([0, 1, 2]))
# False
def is_str_or_int(v):
    return isinstance(v, (int, str))

print(is_str_or_int('string'))
# True

print(is_str_or_int(100))
# True

print(is_str_or_int([0, 1, 2]))
# False
def type_condition(v):
    if isinstance(v, str):
        print('type is str')
    elif isinstance(v, int):
        print('type is int')
    else:
        print('type is not str or int')

type_condition('string')
# type is str

type_condition(100)
# type is int

type_condition([0, 1, 2])
# type is not str or int

Diferença entre tipo() e isinstância()

A diferença entre tipo() e isinstância() é que isinstância() retorna verdadeiro para instâncias de subclasses que herdam a classe especificada como o segundo argumento.

Por exemplo, são definidas a seguinte superclasse (classe base) e subclasse (classe derivada)

class Base:
    pass

class Derive(Base):
    pass

base = Base()
print(type(base))
# <class '__main__.Base'>

derive = Derive()
print(type(derive))
# <class '__main__.Derive'>

A determinação do tipo usando o tipo() só retorna verdadeiro quando os tipos correspondem, mas a isinstância() retorna verdadeiro mesmo para superclasses.

print(type(derive) is Derive)
# True

print(type(derive) is Base)
# False

print(isinstance(derive, Derive))
# True

print(isinstance(derive, Base))
# True

Mesmo para tipos padrão, por exemplo, o bool tipo booleano (verdadeiro,falso), é preciso ter cuidado. bool é uma subclasse do tipo inteiro, portanto isinstância() retorna verdadeiro mesmo para um int do qual é herdado.

print(type(True))
# <class 'bool'>

print(type(True) is bool)
# True

print(type(True) is int)
# False

print(isinstance(True, bool))
# True

print(isinstance(True, int))
# True

Se quiser determinar o tipo exacto, use type(); se quiser determinar o tipo com a herança em consideração, use isinstance().

A função integrada issubclasse() também é fornecida para determinar se uma classe é uma subclasse de outra classe.

print(issubclass(bool, int))
# True

print(issubclass(bool, float))
# False