Pergunta

Qual é a melhor maneira de verificar se um determinado objeto é de um determinado tipo? Como sobre a verificação se as herda objeto de um determinado tipo?

Vamos dizer que tenho uma o objeto. Como faço para verificar se é um str?

Foi útil?

Solução

Para verificar se o é uma instância de str ou qualquer subclasse de str, use isinstance (esta seria a forma "canônica"):

if isinstance(o, str):

Para verificar se o tipo de o é exatamente str (excluir subclasses):

if type(o) is str:

O também seguir funciona, e pode ser útil em alguns casos:

if issubclass(type(o), str):

Funções internas no Python Library Reference para obter informações relevantes.

Uma nota mais: neste caso, se você estiver usando python 2, você pode realmente deseja usar:

if isinstance(o, basestring):

porque isso também vai pegar cadeias de caracteres Unicode ( unicode não é um subclasse de str; ambos str e unicode são subclasses de basestring ). Note-se que basestring não existe mais no python 3, onde há um rigoroso separação de cordas ( str ) e dados binários ( bytes ).

Como alternativa, isinstance aceita uma tupla de classes. Isso irá retornar True se x é uma instância de qualquer subclasse de qualquer um (str, unicode):

if isinstance(o, (str, unicode)):

Outras dicas

O mais Pythonic maneira de verificar o tipo de um objeto é ... não para verificá-lo.

Desde Python incentiva Duck Typing , você deve apenas try...except usar métodos do objeto da maneira que você quer usa-os. Então, se a sua função está à procura de um objeto de arquivo gravável, não verificar que é uma subclasse de file, apenas tentar usar seu método .write()!

Claro que, às vezes, essas abstrações agradáveis ??quebrar e isinstance(obj, cls) é o que você precisa. Mas use com moderação.

isinstance(o, str) voltará True se o é um str ou é de um tipo que herda de str.

type(o) is str voltará True se e somente se o é um str. Ele irá retornar False se o é de um tipo que herda de str.

Depois foi feita a pergunta e respondeu: tipo sugestões foram adicionados ao Python . dicas do tipo em Python permitir tipos de ser verificada, mas de uma maneira muito diferente de linguagens de tipagem estática. dicas do tipo em Python associar os tipos esperados de argumentos com funções como tempo de execução dados acessíveis associados com as funções e isto permite para tipos a ser verificado. Exemplo de sintaxe tipo dica:

def foo(i: int):
    return i

foo(5)
foo('oops')

Neste caso, queremos um erro a ser acionado para foo('oops') desde o tipo anotada do argumento é int. O tipo de sugestão adicionada não causa um erro para ocorrer quando o script é executado normalmente. No entanto, acrescenta atributos para a função que descrevem os tipos esperados que outros programas possam consultar e uso para verificar se há erros de tipo.

Um desses outros programas que podem ser usados ??para localizar o erro tipo é mypy:

mypy script.py
script.py:12: error: Argument 1 to "foo" has incompatible type "str"; expected "int"

(Você pode precisar instalar mypy do seu gerenciador de pacotes. Eu não acho que ele vem com CPython mas parece ter algum nível de "officialness".)

verificação de tipo desta forma é diferente da verificação de tipo em linguagens compiladas de tipagem estática. Porque os tipos são dinâmicas em Python, verificação de tipo deve ser feito em tempo de execução, o que impõe um custo - mesmo em programas corretos - se insistirmos que isso aconteça em todas as hipóteses. verificações explícitas de tipo podem também ser mais restritiva do que o necessário e causar erros desnecessários (por exemplo, se o argumento realmente precisa ser do tipo exatamente list ou é nada iterable suficiente?).

A vantagem de verificação de tipo explícita é que ele pode detectar erros mais cedo e dar mensagens de erro mais claras do que digitar pato. Os requisitos exatos de um tipo de pato só pode ser expressa com documentação externa (espero que seja completa e exata) e erros de tipos incompatíveis pode ocorrer longe de onde são originários.

dicas do tipo do Python se destina a oferecer um compromisso em que os tipos podem ser especificados e marcada, mas não há nenhum custo adicional durante a execução de código de costume.

Os pacotes typing tipo ofertas variáveis ??que podem ser usados ??em pistas tipo de expressar comportamentos necessários sem a necessidade de tipos particulares. Por exemplo, inclui variáveis ??como Iterable e Callable para dicas para especificar a necessidade de qualquer tipo com esses comportamentos.

Enquanto dicas do tipo são a forma mais Pythonic para verificar tipos, muitas vezes é ainda mais Pythonic para não verificar os tipos em tudo e confiar em tipagem pato. dicas de tipo são relativamente novo e o júri ainda está fora de quando eles são a solução mais Pythonic. Uma comparação relativamente incontroversa, mas muito geral: dicas Tipo proporcionar uma forma de documentação que pode ser aplicada, permitir que o código para gerar mais cedo e mais fácil de entender os erros, pode pegar erros que tipagem pato não pode, e pode ser verificado estaticamente (em uma invulgar sentido, mas ele ainda está fora do tempo de execução). Por outro lado, pato digitação tem sido a forma Pythonic por um longo tempo, não impõe a sobrecarga cognitiva de tipagem estática, é menos detalhado, e aceita todos os tipos viáveis ??e então alguns.

Aqui está um exemplo porque pato digitação é mal sem saber quando é perigoso. Por exemplo: Aqui está o código Python (possivelmente omitindo recuo adequada), nota que esta situação é evitável por cuidar de isinstance e issubclassof funções para se certificar de que quando você realmente precisa de um pato, você não obter uma bomba.

class Bomb:
    def __init__(self):
        ""

    def talk(self):
        self.explode()

    def explode(self):
        print "BOOM!, The bomb explodes."

class Duck:
    def __init__(self):
        ""
    def talk(self):
        print "I am a duck, I will not blow up if you ask me to talk."    

class Kid:
    kids_duck = None

    def __init__(self):
        print "Kid comes around a corner and asks you for money so he could buy a duck."

    def takeDuck(self, duck):
        self.kids_duck = duck
        print "The kid accepts the duck, and happily skips along"

    def doYourThing(self):
        print "The kid tries to get the duck to talk"
        self.kids_duck.talk()

myKid = Kid()
myBomb = Bomb()
myKid.takeDuck(myBomb)
myKid.doYourThing()
isinstance(o, str)

Link para docs

Eu acho que a coisa legal sobre o uso de uma linguagem dinâmica como Python é que você realmente não deve ter que verificar algo assim.

Gostaria apenas de chamar os métodos necessários no seu objeto e pegar um AttributeError. Mais tarde, isso permitirá que você para chamar seus métodos com outro (aparentemente não relacionados) objetos para realizar diferentes tarefas, como zombando de um objeto para testar.

Eu usei isso muito quando a obtenção de dados fora da web com urllib2.urlopen() que retorna um arquivo como objeto. Isto pode, por sua vez pode ser passado para quase qualquer método que lê um arquivo, porque ele implementa o mesmo método read() como um arquivo real.

Mas eu tenho certeza que há um tempo e lugar para usar isinstance(), caso contrário, provavelmente não estaria lá:)

Para Hugo:

Você provavelmente list média em vez de array, mas que aponta para todo o problema com a verificação de tipo - você não quer saber se o objeto em questão é uma lista, você quer saber se é algum tipo de sequência ou se é um único objeto. Portanto, tente usá-lo como uma seqüência.

Digamos que você deseja adicionar o objeto para uma seqüência existente, ou se é uma sequência de objetos, adicioná-los todos

try:
   my_sequence.extend(o)
except TypeError:
  my_sequence.append(o)

Um truque com isso é se você estiver trabalhando com cordas e / ou seqüências de cordas - que é complicado, como uma string é frequentemente considerada como um único objeto, mas é também uma sequência de caracteres. Pior do que isso, como é realmente uma seqüência de seqüências de comprimento único.

Eu costumo escolher para projetar o meu API para que ele só aceita um único valor ou uma sequência - torna as coisas mais fáceis. Não é difícil colocar um [ ] em torno de seu valor único quando você passá-lo em caso de necessidade.

(Embora isso pode causar erros com cordas, como eles se parecem (são) sequências.)

Para validações tipo mais complexas eu gosto typeguard 's abordagem de validar com base em anotações dica do tipo python :

from typeguard import check_type
from typing import List

try:
    check_type('mylist', [1, 2], List[int])
except TypeError as e:
    print(e)

Você pode executar validações muito complexas de forma muito limpo e legível.

check_type('foo', [1, 3.14], List[Union[int, float]])
# vs
isinstance(foo, list) and all(isinstance(a, (int, float)) for a in foo) 

Você pode verificar com o abaixo da linha para verificar qual personagem digite o valor dado é:

def chr_type(chrx):
    if chrx.isalpha()==True:
        return 'alpha'
    elif chrx.isdigit()==True:
        return 'numeric'
    else:
        return 'nothing'

chr_type("12)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top