Existe uma maneira simples de determinar se uma variável é uma lista, dicionário ou outra coisa? Estou recebendo um objeto de volta que pode ser do tipo e preciso saber a diferença.
python
dictionary
types
typeof
Justin Ethier
fonte
fonte
try
não ajuda. Por exemplo, se você sabia que um usuário poderia passar uma string ou uma matriz, ambos podem ser indexados, mas esse índice significa algo completamente diferente. Simplesmente contar com um try-catch nesses casos falhará de maneiras inesperadas e estranhas. Uma solução é criar um método separado, outra para adicionar uma pequena verificação de tipo. Eu pessoalmente prefiro o comportamento polimórfico ao longo de vários métodos que fazer quase a mesma coisa ... mas isso é apenas me :)Respostas:
Existem duas funções internas que ajudam a identificar o tipo de um objeto. Você pode usar
type()
se precisar o tipo exato de um objeto, eisinstance()
para verificar o tipo de um objeto contra alguma coisa. Geralmente, você deseja usar naisistance()
maioria das vezes, uma vez que é muito robusto e também suporta herança de tipo.Para obter o tipo real de um objeto, use a
type()
função interna. Passar um objeto como o único parâmetro retornará o objeto de tipo desse objeto:Obviamente, isso também funciona para tipos personalizados:
Observe que
type()
retornará apenas o tipo imediato do objeto, mas não poderá informar sobre a herança do tipo.Para cobrir isso, você deve usar a
isinstance
função Obviamente, isso também funciona para tipos internos:isinstance()
geralmente é a maneira preferida de garantir o tipo de um objeto, porque ele também aceita tipos derivados. Portanto, a menos que você realmente precise do objeto de texto (por qualquer motivo), o usoisinstance()
é preferíveltype()
.O segundo parâmetro de
isinstance()
também aceita uma tupla de tipos, portanto, é possível verificar vários tipos de uma só vez.isinstance
retornará true, se o objeto for de um desses tipos:fonte
is
em vez de==
como os tipos são singletonsisinstance
é a forma preferida de qualquer forma, então, nem==
ouis
precisa ser usado.type
é a melhor resposta. Há momentos em queisinstance
é a melhor resposta e há momentos em que a digitação de pato é a melhor resposta. É importante conhecer todas as opções para poder escolher qual é a mais apropriada para a situação.type(foo) is SomeType
que seria melhor do queisinstance(foo, SomeType)
.isinstance
como base de dados (verificando uma variedade de tipos) e com limpe também uma sintaxe, que possui a grande vantagem de capturar subclasses. alguém usandoOrderedDict
odiaria que seu código falhasse porque ele aceita dictos puros.Você pode fazer isso usando
type()
:fonte
Pode ser mais Pythonic usar um bloco
try
...except
Dessa forma, se você tem uma classe que grasna como uma lista, ou grasna como um dicionário, ele irá se comportar corretamente, independentemente do que seu tipo realmente é.Para esclarecer, o método preferido de "dizer a diferença" entre os tipos de variáveis é com algo chamado tipagem de pato : desde que os métodos (e tipos de retorno) aos quais uma variável responde sejam o que sua sub-rotina espera, trate-a como o esperado. ser estar. Por exemplo, se você tem uma classe que sobrecarrega os operadores de colchete com
getattr
esetattr
, mas usa algum esquema interno engraçado, seria apropriado que ele se comporte como um dicionário, se é isso que ele está tentando imitar.O outro problema com a
type(A) is type(B)
verificação é que, seA
for uma subclasse deB
, ela avaliafalse
quando, programaticamente, você esperaria que fossetrue
. Se um objeto é uma subclasse de uma lista, ele deve funcionar como uma lista: a verificação do tipo apresentado na outra resposta impedirá isso. (isinstance
funcionará, no entanto).fonte
try
...except
é uma boa solução quando você deseja lidar com erros, mas não quando decide um comportamento com base no tipo.Nas instâncias do objeto, você também tem o:
atributo. Aqui está um exemplo retirado do console do Python 3.3
Observe que no python 3.xe nas classes New-Style (disponíveis opcionalmente no Python 2.6) a classe e o tipo foram mesclados e isso pode levar a resultados inesperados. Principalmente por esse motivo, minha maneira favorita de testar tipos / classes é a função integrada da instância .
fonte
__class__
está bem no Python 2.x, os únicos objetos no Python que não têm__class__
atributo são as classes de estilo antigo AFAIK. A propósito, não entendo sua preocupação com o Python 3 - nessa versão, apenas todo objeto tem um__class__
atributo que aponta para a classe apropriada.Determinar o tipo de um objeto Python
Determine o tipo de um objeto com
type
Embora funcione, evite atributos de sublinhado duplo como
__class__
- eles não são semanticamente públicos e, embora talvez não seja o caso, as funções internas geralmente têm um comportamento melhor.verificação de tipo
Bem, essa é uma pergunta diferente, não use type - use
isinstance
:Isso cobre o caso em que o usuário pode estar fazendo algo inteligente ou sensível ao subclassificar
str
- de acordo com o princípio da Substituição de Liskov, você deseja usar instâncias de subclasse sem quebrar seu código - eisinstance
suporta isso.Usar abstrações
Ainda melhor, você pode procurar uma Classe Base Abstrata específica de
collections
ounumbers
:Ou simplesmente não verifique explicitamente o tipo
Ou, talvez o melhor de tudo, use digitação de pato e não verifique explicitamente seu código. A digitação de pato suporta a substituição de Liskov com mais elegância e menos verbosidade.
Conclusão
type
para realmente obter a classe de uma instância.isinstance
para verificar explicitamente subclasses reais ou abstrações registradas.fonte
try
/ emexcept
vez de verificar explicitamente.Você pode usar
type()
ouisinstance()
.Esteja avisado de que você pode refogar
list
ou qualquer outro tipo atribuindo uma variável no escopo atual do mesmo nome.Acima, vemos que
dict
é reatribuído a uma string, portanto, o teste:... falha.
Para contornar isso e usar com
type()
mais cautela:fonte
dict
string também falhará em muitos outros códigos, comodict([("key1", "value1"), ("key2", "value2")])
. A resposta para esse tipo de problema é "Então não faça isso" . Não sombreie os nomes dos tipos internos e espere que as coisas funcionem corretamente.Embora as perguntas sejam bastante antigas, eu me deparei com isso enquanto descobria uma maneira adequada, e acho que ainda precisa ser esclarecida, pelo menos para o Python 2.x (não checou o Python 3, mas como o problema surge com as classes clássicas que foram lançadas nessa versão, provavelmente não importa).
Aqui, estou tentando responder à pergunta do título: como posso determinar o tipo de um objeto arbitrário ? Outras sugestões sobre o uso ou não do isinstance são boas em muitos comentários e respostas, mas não estou abordando essas preocupações.
O principal problema da
type()
abordagem é que ela não funciona corretamente com instâncias de estilo antigo :A execução desse snippet renderia:
O que, argumento, não é o que a maioria das pessoas esperaria.
A
__class__
abordagem é a mais próxima da correção, mas não funcionará em um caso crucial: quando o objeto passado é uma classe de estilo antigo (não uma instância!), Pois esses objetos não possuem esse atributo.Este é o menor trecho de código que eu poderia pensar que satisfaz essa pergunta legítima de uma maneira consistente:
fonte
tenha cuidado usando isinstance
mas digite
fonte
Como um aparte das respostas anteriores, vale a pena mencionar a existência,
collections.abc
que contém várias classes básicas abstratas (ABCs) que complementam a digitação de patos.Por exemplo, em vez de verificar explicitamente se algo é uma lista com:
você poderia, se estiver interessado apenas em ver se o objeto que você possui permite obter itens, use
collections.abc.Sequence
:se você estiver estritamente interessado em objetos que permitem obter, configurar e excluir itens (por exemplo, seqüências mutáveis ), você optaria
collections.abc.MutableSequence
.Muitos outros ABCs são definidas lá,
Mapping
para objetos que podem ser usados como mapas,Iterable
,Callable
, et cetera. Uma lista completa de tudo isso pode ser vista na documentação paracollections.abc
.fonte
Em geral, você pode extrair uma string do objeto com o nome da classe,
e usá-lo para comparação,
fonte
Em muitos casos práticos, em vez de usar
type
ouisinstance
você também pode usar@functools.singledispatch
, que é usado para definir funções genéricas ( função composta de várias funções implementando a mesma operação para tipos diferentes ).Em outras palavras, você gostaria de usá-lo quando tiver um código como o seguinte:
Aqui está um pequeno exemplo de como funciona:
Adicionalmente, podemos usar classes abstratas para cobrir vários tipos de uma só vez:
fonte
type()
é uma solução melhor do queisinstance()
, especialmente parabooleans
:True
eFalse
são apenas palavras-chave que significam1
e0
em python. Portanto,e
ambos retornam
True
. Ambos os booleanos são uma instância de um número inteiro.type()
, no entanto, é mais inteligente:retorna
False
.fonte