2009-04-01 9 views

risposta

153
isinstance() 

Nel tuo caso, isinstance("this is a string", str) tornerà True.

Si consiglia inoltre di leggere questo: http://www.canonical.org/~kragen/isinstance/

+4

Direi che (l'OP) dovrebbe * sicuramente * leggere il link di riferimento, che fornisce molti dettagli sul perché il controllo del tipo di un oggetto è di solito una cattiva idea, e quello che probabilmente dovresti fare invece. –

+3

dalla memoria isinstance (obj, basestring) preleverà anche stringhe unicode ... –

+2

dovresti usare basestr, non str. altrimenti non sceglierai unicode. (anche se per 3.x penso che str * sia * the basestr) – hasen

4

Sei molto vicino! string è un modulo, non un tipo. Probabilmente si desidera confrontare il tipo di obj contro l'oggetto tipo per le stringhe, e cioè str:

type(obj) == str # this works because str is already a type 

alternativa:

type(obj) == type('') 

nota, in Python 2, se obj è un tipo unicode, allora né di quanto sopra funzionerà. Né sarà isinstance(). Vedi i commenti di John a questo post su come aggirare questo ... Ho cercato di ricordarlo per circa 10 minuti ora, ma avevo un blocco di memoria!

+2

Utilizzare basestring con isinstance() per ottenere sia str che unicode. –

+0

-1 per non menzionare che il typecheck è una cattiva idea – nosklo

2

penso che questo dovrebbe farlo

if isinstance(obj, str) 
+0

-1 per non menzionare che typecheck è una cattiva idea – nosklo

22

Per altri tipi, controllare il modulo di types:

>>> import types 
>>> x = "mystring" 
>>> isinstance(x, types.StringType) 
True 
>>> x = 5 
>>> isinstance(x, types.IntType) 
True 
>>> x = None 
>>> isinstance(x, types.NoneType) 
True 

P.S. Typechecking è una cattiva idea.

32

isinstance opere:

if isinstance(obj, MyClass): do_foo(obj) 

ma, tenere a mente: se sembra un'anatra, e se suona come un'anatra, è un'anatra.

EDIT: Per il tipo di None, si può semplicemente fare:

if obj is None: obj = MyClass() 
+0

'def distance_from_zero (n): if isinstance (n, int) o isinstance (n, float) : ritorno abs (n) altro: ritorno "No" stampa distance_from_zero (true) ' Questa restituisce un "1" invece di "No". Come aggirare questo? –

+0

Se si desidera utilizzare 'isinstance' ma controllare anche per' None', quindi 'isinstance (obj, (MyClass, type (None)))' funziona. 'types.NoneType' è stato rimosso da Python 3 quindi non è così portatile come' type (None) 'per ottenere un riferimento a' NoneType'. –

+0

Funziona per me. Grazie :) –

10

si può sempre utilizzare il type(x) == type(y) trucco, dove y è qualcosa con tipo noto.

# check if x is a regular string 
type(x) == type('') 
# check if x is an integer 
type(x) == type(1) 
# check if x is a NoneType 
type(x) == type(None) 

Spesso ci sono modi migliori per farlo, in particolare con qualsiasi python recente. Ma se vuoi solo ricordare una cosa, puoi ricordarla.

In questo caso, i modi migliore sarebbe:

# check if x is a regular string 
type(x) == str 
# check if x is either a regular string or a unicode string 
type(x) in [str, unicode] 
# alternatively: 
isinstance(x, basestring) 
# check if x is an integer 
type(x) == int 
# check if x is a NoneType 
x is None 

Nota l'ultimo caso: non c'è una sola istanza di NoneType in python, e che è None.Vedrai NoneType molto in eccezioni (TypeError: 'NoneType' object is unsubscriptable - mi succede sempre ..) ma non avrai quasi mai bisogno di farvi riferimento nel codice.

Infine, come fa notare fengshaun, digitare check in python non è sempre una buona idea. È più sdolcinato usare semplicemente il valore come se fosse il tipo che ci si aspetta e intercettare (o consentire di propagare) le eccezioni che ne derivano.

+1

Per quello che vale, isinstance() è il modo preferito di controllare i tipi in Python (quando devi farlo). –

3

Io uso type(x) == type(y)

Per esempio, se voglio controllare una cosa è un array: controllo

type(x) == type([]) 

stringa:

type(x) == type('') or type(x) == type(u'') 

Se si desidera controllare contro nessuno, l'uso è

x is None 
+0

-1 per non menzionare che il typecheck è una cattiva idea – nosklo

+0

eh? perché è una cattiva idea in generale? È solo una cattiva idea per le stringhe (per la versione 3.0) perché ci sono due tipi di stringhe, str e unicode. Per gli array, è una buona idea imho. – hasen

+0

@hasen: è una cattiva idea nel complesso. Cosa succede se definisco il mio tipo che si comporta come un array ma, ad esempio, recupera i valori da un database? Il tuo codice fallirà con il mio tipo senza motivo. – nosklo

28

Innanzitutto, evitare tutti i confronti di tipo. Sono molto, molto raramente necessari. A volte, aiutano a controllare i tipi di parametri in una funzione - anche questo è raro. I dati di tipo errato generano un'eccezione e questo è tutto ciò di cui avrai mai bisogno.

Tutte le funzioni di conversione di base verranno mappate come uguali alla funzione di tipo.

type(9) is int 
type(2.5) is float 
type('x') is str 
type(u'x') is unicode 
type(2+3j) is complex 

Ci sono alcuni altri casi.

isinstance('x', basestring) 
isinstance(u'u', basestring) 
isinstance(9, int) 
isinstance(2.5, float) 
isinstance((2+3j), complex) 

Nessuno, BTW, non ha mai bisogno di questo tipo di controllo del tipo. Nessuna è l'unica istanza di NoneType. L'oggetto None è un Singleton. Basta controllare per Nessuno

variable is None 

BTW, non utilizzare quanto sopra in generale. Utilizzare le ordinarie eccezioni e il proprio polimorfismo naturale di Python.

+2

Se si stanno convalidando gli input da una DSL, è necessario tutto ciò, anche 'NoneType'. Cosa succede se un parametro può essere un 'str',' unicode' o 'None'? 'isinstance (x, (str, unicode, types.NoneType))' è molto più pulito del controllo di 'None'. Se si stanno creando strumenti per il calcolo differito o se si sta per avviare un processo lungo o ad alta intensità di risorse, è utile rilevare gli errori di tipo "prima" in anticipo, durante una fase di convalida personalizzata. Questa è stata una parte fondamentale di quasi tutti i progetti di calcolo scientifico su cui abbia mai lavorato. Di tutti i progetti di sviluppo che ho visto, più ne ho avuto bisogno che non averlo fatto. – ely

5

E 'perché si deve scrivere

s="hello" 
type(s) == type("") 

tipo accetta un'istanza e restituisce il suo tipo. In questo caso devi confrontare due tipi di istanze.

Se è necessario eseguire il controllo preventivo, è meglio controllare un'interfaccia supportata rispetto al tipo.

Il tipo in realtà non ti dice molto, a parte il fatto che il tuo codice vuole un'istanza di un tipo specifico, indipendentemente dal fatto che potresti avere un'altra istanza di un tipo completamente diverso che andrebbe perfettamente bene perché implementa la stessa interfaccia

Ad esempio, si supponga di avere questo codice

def firstElement(parameter): 
    return parameter[0] 

Ora, supponiamo che tu dici: io voglio questo codice per accettare solo una tupla.

import types 

def firstElement(parameter): 
    if type(parameter) != types.TupleType: 
     raise TypeError("function accepts only a tuple") 
    return parameter[0] 

Questo riduce la riusabilità di questa routine. Non funzionerà se passi una lista, una stringa o un numpy.array.Qualcosa di meglio sarebbe

def firstElement(parameter): 
    if not (hasattr(parameter, "__getitem__") and callable(getattr(parameter,"__getitem__"))): 
     raise TypeError("interface violation") 
    return parameter[0] 

ma non c'è nessun punto nel farlo: parametro [0] solleverà un'eccezione se il protocollo non è soddisfatto comunque ... questo, naturalmente, a meno che non si vuole impedire che gli effetti collaterali o di dover recuperare dalle chiamate che è possibile richiamare prima di non riuscire. (Stupido) esempio, solo per fare il punto:

def firstElement(parameter): 
    if not (hasattr(parameter, "__getitem__") and callable(getattr(parameter,"__getitem__"))): 
     raise TypeError("interface violation") 
    os.system("rm file") 
    return parameter[0] 

in questo caso, il codice solleverà un'eccezione prima di eseguire il() chiamata di sistema. Senza i controlli dell'interfaccia, avresti rimosso il file e quindi sollevato l'eccezione.

+0

Grazie per aver indicato il modo preferito per verificare la presenza di interfacce. Molte delle risposte qui lo menzionano, ma pochi danno esempi di ciò che è buono, invece. Non risponde ancora direttamente alla mia domanda personale (sto cercando di separare una lista di stringhe, contenente molti elementi significativi, da una stringa, che contiene molti elementi non significativi. – Nick

1

Il tipo non funziona su alcune classi. Se non siete sicuri del tipo di oggetto utilizzare il metodo __class__, come così:

>>>obj = 'a string' 
>>>obj.__class__ == str 
True 

veda anche questo articolo - http://www.siafoo.net/article/56

0

Per ottenere il tipo, utilizzare il membro __class__, come in unknown_thing.__class__

Parlare di battitura d'anatra è inutile qui perché non risponde ad una domanda perfettamente valida. Nel mio codice applicazione non ho mai bisogno di sapere il tipo di qualcosa, ma è comunque utile avere un modo per imparare il tipo di un oggetto. A volte ho bisogno di ottenere la classe reale per convalidare un test unitario. La duck typing si intromette perché tutti gli oggetti possibili hanno la stessa API, ma solo uno è corretto. Inoltre, a volte sto mantenendo il codice di qualcun altro, e non ho idea di che tipo di oggetto sono stato passato. Questo è il mio più grande problema con linguaggi tipizzati dinamicamente come Python. La versione 1 è molto facile e veloce da sviluppare. La versione 2 è un fastidio per i buns, specialmente se non hai scritto la versione 1. Quindi a volte, quando lavoro con una funzione che non ho scritto, ho bisogno di conoscere il tipo di parametro, solo così so quali metodi posso chiamare su di esso.

Ecco dove il parametro __class__ è utile. Questo (per quanto posso dire) è il modo migliore (forse l'unico modo) per ottenere il tipo di un oggetto.

3

Uso str invece di stringa

type (obj) == str 

Spiegazione

>>> a = "Hello" 
>>> type(a)==str 
True 
>>> type(a) 
<type 'str'> 
>>> 
0

È possibile confrontare i corsi per il livello di controllo.

#!/usr/bin/env python 
#coding:utf8 

class A(object): 
    def t(self): 
     print 'A' 
    def r(self): 
     print 'rA', 
     self.t() 

class B(A): 
    def t(self): 
     print 'B' 

class C(A): 
    def t(self): 
     print 'C' 

class D(B, C): 
    def t(self): 
     print 'D', 
     super(D, self).t() 

class E(C, B): 
    pass 

d = D() 
d.t() 
d.r() 

e = E() 
e.t() 
e.r() 

print isinstance(e, D) # False 
print isinstance(e, E) # True 
print isinstance(e, C) # True 
print isinstance(e, B) # True 
print isinstance(e, (A,)) # True 
print e.__class__ >= A, #False 
print e.__class__ <= C, #False 
print e.__class__ < E, #False 
print e.__class__ <= E #True 
Problemi correlati