types check - Qual è il modo canonico per verificare la presenza di un tipo in Python?



typeof python3 (9)

Penso che la cosa bella dell'uso di un linguaggio dinamico come Python sia che non dovresti davvero controllare qualcosa del genere.

Vorrei solo chiamare i metodi richiesti sul tuo oggetto e catturare un AttributeError . In seguito, ciò ti consentirà di chiamare i tuoi metodi con altri oggetti (apparentemente non correlati) per svolgere diversi compiti, come ad esempio la simulazione di un oggetto per il test.

L'ho usato molto quando ho scaricato i dati dal web con urllib2.urlopen() che restituisce un file come oggetto. Questo può a sua volta essere passato a quasi tutti i metodi che legge da un file, perché implementa lo stesso metodo read() come un file reale.

Ma sono sicuro che c'è un tempo e un luogo per usare isinstance() , altrimenti probabilmente non ci sarebbe :)

Qual è il modo migliore per verificare se un determinato oggetto è di un determinato tipo? Che ne dici di verificare se l'oggetto eredita da un determinato tipo?

Diciamo che ho un oggetto o . Come posso verificare se si tratta di una str ?


isinstance(o, str) restituirà true se o è uno str o è di un tipo che eredita da str .

type(o) is str restituirà true se e solo se o è uno str. Restituirà false se o è di un tipo che eredita da str . ----


Ecco un esempio per cui la digitazione anatra è malvagia senza sapere quando è pericolosa. Per esempio: Ecco il codice Python (forse omettendo il rientro appropriato), nota che questa situazione è evitabile prendendosi cura delle funzioni isinstance ed emubclassof per assicurarsi che quando hai davvero bisogno di un'anatra, non ottieni una 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()

Il modo più Python per controllare il tipo di un oggetto è ... non controllarlo.

Poichè Python incoraggia Duck Typing , dovresti try...except usare i metodi dell'oggetto nel modo in cui vuoi usarli. Quindi se la tua funzione sta cercando un oggetto file scrivibile, non controllare che sia una sottoclasse di file , prova a usare il suo metodo .write() !

Certo, a volte queste belle astrazioni si rompono e isinstance(obj, cls) è ciò di cui hai bisogno. Ma usa con parsimonia.


Puoi verificare con la riga sottostante per verificare quale tipo di carattere il valore dato è:

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

chr_type("12)

Per verificare se o è un'istanza di str o qualsiasi sottoclasse di str , usa isinstance (questo sarebbe il modo "canonico"):

if isinstance(o, str):

Per verificare se il tipo di o è esattamente str (escludere sottoclassi):

if type(o) is str:

Quanto segue funziona anche e può essere utile in alcuni casi:

if issubclass(type(o), str):

Vedi Funzioni incorporate nella Riferimenti bibliografici Python per informazioni rilevanti.

Ancora una nota: in questo caso, se stai usando python 2, potresti effettivamente voler usare:

if isinstance(o, basestring):

perché questo catturerà anche stringhe Unicode ( unicode non è una sottoclasse di str ; sia str che unicode sono sottoclassi di basestring ). Nota che basestring non esiste più in python 3, dove c'è una stretta separazione tra stringhe ( str ) e dati binari ( bytes ).

In alternativa, isinstance accetta una tupla di classi. Questo restituirà True se x è un'istanza di qualsiasi sottoclasse di qualsiasi (str, unicode):

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

Per Hugo:

Probabilmente vuoi dire list piuttosto che array , ma questo punta all'intero problema con il controllo di tipo - non vuoi sapere se l'oggetto in questione è un elenco, vuoi sapere se è una specie di sequenza o se è un singolo oggetto. Quindi prova ad usarlo come una sequenza.

Supponi di voler aggiungere l'oggetto a una sequenza esistente o se si tratta di una sequenza di oggetti, aggiungili tutti

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

Un trucco con questo è se si lavora con stringhe e / o sequenze di stringhe - questo è complicato, poiché una stringa viene spesso considerata come un singolo oggetto, ma è anche una sequenza di caratteri. Peggio ancora, dato che è davvero una sequenza di stringhe a lunghezza singola.

Di solito scelgo di progettare la mia API in modo che accetti solo un singolo valore o una sequenza: semplifica le cose. Non è difficile mettere un [ ] attorno al tuo singolo valore quando lo passi, se necessario.

(Anche se questo può causare errori con le stringhe, poiché assomigliano a (sono) sequenze.)


Dopo che la domanda è stata fatta e ha risposto, sono stati aggiunti suggerimenti di tipo a Python . I suggerimenti di tipo in Python consentono di controllare i tipi, ma in un modo molto diverso dalle lingue tipizzate in modo statico. I suggerimenti di tipo in Python associano i tipi di argomenti previsti con funzioni come dati accessibili in runtime associati alle funzioni e questo consente di controllare i tipi. Esempio di sintassi suggerimento tipo:

def foo(i: int):
    return i

foo(5)
foo('oops')

In questo caso vogliamo che venga attivato un errore per foo('oops') poiché il tipo annotato dell'argomento è int . Il suggerimento di tipo aggiunto non causa un errore quando lo script viene eseguito normalmente. Tuttavia, aggiunge attributi alla funzione che descrive i tipi previsti che altri programmi possono interrogare e utilizzare per verificare gli errori di tipo.

Uno di questi altri programmi che possono essere utilizzati per trovare l'errore di tipo è mypy :

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

(Potrebbe essere necessario installare mypy dal proprio gestore di pacchetti. Non penso che sia fornito con CPython ma sembra avere un certo livello di "ufficialità".)

Digitare il controllo in questo modo è diverso dal tipo di controllo in lingue compilate in modo statico. Poiché i tipi sono dinamici in Python, il controllo dei tipi deve essere eseguito in fase di runtime, il che impone un costo - anche sui programmi corretti - se insistiamo sul fatto che ciò accada in ogni caso. I controlli espliciti dei tipi possono anche essere più restrittivi del necessario e causare errori non necessari (ad esempio, l'argomento deve davvero essere di tipo list o è sufficiente qualcosa di iterabile?).

L'aspetto positivo del controllo di tipo esplicito è che può rilevare errori in precedenza e fornire messaggi di errore più chiari rispetto alla digitazione anatra. I requisiti esatti di un tipo di anatra possono essere espressi solo con la documentazione esterna (si spera sia accurato e accurato) e gli errori da tipi incompatibili possono verificarsi lontano da dove provengono.

I suggerimenti tipo di Python hanno lo scopo di offrire un compromesso in cui i tipi possono essere specificati e controllati, ma non vi è alcun costo aggiuntivo durante l'esecuzione del codice usuale.

Il pacchetto di typing offre variabili di tipo che possono essere utilizzate nei suggerimenti di tipo per esprimere i comportamenti necessari senza richiedere tipi particolari. Ad esempio, include variabili come Iterable e Callable per i suggerimenti per specificare la necessità di qualsiasi tipo con tali comportamenti.

Mentre i suggerimenti sui tipi sono il modo più pazzesco per controllare i tipi, spesso è ancora più Pythonico non controllare i tipi e fare affidamento sulla digitazione anatra. I suggerimenti di tipo sono relativamente nuovi e la giuria è ancora fuori quando sono la soluzione più pitonica. Un confronto relativamente incontrovertibile ma molto generale: i suggerimenti di tipo forniscono una forma di documentazione che può essere applicata, consentono al codice di generare errori precedenti e più facili da capire, possono rilevare errori che non possono essere digitati e possono essere controllati staticamente (in un senso, ma è ancora al di fuori del runtime). D'altra parte, la digitazione anatra è stata per molto tempo il modo Pythonico, non impone il sovraccarico cognitivo della tipizzazione statica, è meno prolissa e accetterà tutti i tipi possibili e quindi alcuni.


Simulazione dell'operatore ternario di Python.

Per esempio

a, b, x, y = 1, 2, 'a greather than b', 'b greater than a'
result = (lambda:y, lambda:x)[a > b]()

produzione:

'b greater than a'




python types