Quelle est la façon canonique de vérifier le type en Python?

Quelle est la meilleure façon de vérifier si un objet est d'un type donné? Comment agit de vérifier si l'objet hérite d'un type donné?

disons que j'ai un objet o . Comment puis-je vérifier si c'est un str ?

931
demandé sur Peter Mortensen 2008-09-30 15:00:10

10 réponses

pour vérifier si o est une instance de str ou de toute sous-classe de str , utilisez isinstance (ce serait la voie "canonique"):

if isinstance(o, str):

pour vérifier si le type de o est exactement str (à l'exclusion des sous-classes):

if type(o) is str:

fonctionne aussi, et peut être utile dans certains cas:

if issubclass(type(o), str):

voir intégré Fonctions dans la bibliothèque de référence Python pour des informations pertinentes.

encore une note: dans ce cas, si vous utilisez python 2, Vous pouvez en fait vouloir utiliser:

if isinstance(o, basestring):

car cela captera aussi les chaînes Unicode ( unicode n'est pas une sous-classe de str ; str et unicode sont toutes deux des sous-classes de basestring ). Notez que basestring Non plus existe en python 3, où il y a une séparation stricte de cordes ( str ) et des données binaires( bytes ).

alternativement, isinstance accepte un tuple de classes. Ceci retournera True si x est une instance d'une sous-classe quelconque de (str, unicode):

if isinstance(o, (str, unicode)):
1152
répondu Fredrik Johansson 2018-09-09 23:53:40

Le plus Pythonic moyen de vérifier le type d'un objet est... pas de le vérifier.

puisque Python encourage Duck Typing , vous devez juste try...except pour utiliser les méthodes de l'objet de la façon dont vous voulez les utiliser. Donc, si votre fonction est à la recherche d'un objet de fichier accessible en écriture, don't vérifiez que c'est une sous-classe de file , essayez juste d'utiliser sa méthode .write() !

bien sûr, parfois ces belles abstractions se décomposent et isinstance(obj, cls) est ce dont vous avez besoin. Mais utilisez avec parcimonie.

149
répondu Dan Lenski 2018-09-09 23:55:36

isinstance(o, str) retournera true si o est un str ou est d'un type qui hérite de str .

type(o) is str sera de retour true si et seulement si o est un str. Il retournera false si o est d'un type qui hérite de str . ----

41
répondu Herge 2018-04-27 17:51:46

après que la question a été posée et a répondu, des indices de type ont été ajoutés à Python . Les indices de Type en Python permettent de vérifier les types mais d'une manière très différente des langages statiquement typés. Les indices de Type en Python associent les types d'arguments attendus avec des fonctions de données accessibles à l'exécution associées à des fonctions et ce permet pour les types à vérifier. Exemple de syntaxe type hint:

def foo(i: int):
    return i

foo(5)
foo('oops')

dans ce cas, nous voulons qu'une erreur soit déclenchée pour foo('oops') puisque le type annoté de l'argument est int . L'indicateur de type ajouté ne cause pas une erreur à se produire lorsque le script est exécuté normalement. Cependant, il ajoute des attributs à la fonction décrivant les types attendus que d'autres programmes peuvent interroger et utiliser pour vérifier les erreurs de type.

un de ces autres programmes qui peuvent être utilisés pour trouver l'erreur de type est mypy :

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

(vous pourriez avoir besoin d'installer mypy à partir de votre gestionnaire de paquets. Je ne pense pas qu'il vienne avec CPython mais semble avoir un certain niveau de "officialité".)

La vérification de Type

de cette façon est différente de la vérification de type dans les langues compilées statiquement dactylographiées. Parce que les types sont dynamiques en Python, la vérification de type doit être faite à l'exécution, ce qui impose un coût -- même sur les programmes corrects -- si nous insistons pour que cela arrive à toutes les chances. Les contrôles de type explicites peuvent aussi être plus restrictifs que nécessaire et causer des erreurs inutiles (par exemple, est-ce que l'argument doit vraiment être de type list ou est-ce que quelque chose d'itérable est suffisant?).

l'avantage de la vérification de type explicite est qu'elle permet de détecter les erreurs plus tôt et de donner des messages d'erreur plus clairs que la vérification de type canard. Les exigences exactes d'un type de canard ne peuvent être exprimées qu'avec une documentation externe (espérons qu'elle soit complète et précise) et les erreurs de types incompatibles peuvent se produire loin d'où elles proviennent.

Les indices de type

de Python sont destinés à offrir un compromis où les types peuvent être spécifiés et vérifiés mais il n'y a pas de coût supplémentaire lors de l'exécution de code habituelle.

le paquet typing offre des variables de type qui peuvent être utilisées dans les indices de type pour exprimer les comportements nécessaires sans exiger des types particuliers. Par exemple, il inclut des variables telles que Iterable et Callable pour des conseils de spécifier le besoin de tout type avec ces comportements.

alors que les indices de type sont le moyen le plus pythonique de vérifier les types, il est souvent encore plus pythonique de ne pas vérifier les types du tout et de compter sur duck typing. Les indices de Type sont relativement nouveaux et le jury est toujours sur quand ils sont la solution la plus pythonique. Une comparaison relativement peu controversée mais très générale: les indices de Type fournissent une forme de documentation qui peut être appliquée, permettent au code de générer plus tôt et plus facile à comprendre les erreurs, peut attraper des erreurs que la dactylographie de canard ne peut pas, et peut être vérifié statiquement (dans un sens inhabituel, mais il est toujours en dehors de l'exécution). D'un autre côté, Duck typing a été la voie pythonique pendant une longue période, Ne pas imposer la tête cognitive de static typing, est moins verbeux, et acceptera tous les types viables et puis certains.

18
répondu Praxeolitic 2018-01-10 06:22:16

voici un exemple pourquoi taper duck est malfaisant sans savoir quand c'est dangereux. Par exemple: voici le code Python (omettant éventuellement une indentation correcte), notez que ceci situation est évitable en prenant soin d'isinstance et issubclassof fonctions pour s'assurer que lorsque vous avez vraiment besoin d'un canard, vous ne obtenez pas une bombe.

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()
15
répondu Dmitry 2013-10-28 05:30:58
isinstance(o, str)

lien vers docs

10
répondu Alexander Kojevnikov 2018-03-14 06:37:39

je pense que la chose cool à propos de l'utilisation d'un langage dynamique comme Python est que vous ne devriez vraiment pas avoir à vérifier quelque chose comme ça.

j'appellerais simplement les méthodes requises sur votre objet et j'attraperais un AttributeError . Plus tard, cela vous permettra d'appeler vos méthodes avec d'autres objets (apparemment sans rapport) pour accomplir différentes tâches, comme se moquer d'un objet pour le tester.

j'ai beaucoup utilisé ceci quand obtenir des données hors du web avec urllib2.urlopen() qui renvoie un fichier comme objet. Cela peut à son tour être passé à presque n'importe quelle méthode qui lit à partir d'un fichier, parce qu'elle implémente la même méthode read() qu'un fichier réel.

mais je suis sûr qu'il y a un moment et un endroit pour utiliser isinstance() , sinon il ne serait probablement pas là:)

6
répondu Will Harding 2017-11-11 13:34:30

À Hugo:

vous voulez probablement dire list plutôt que array , mais cela indique tout le problème avec la vérification de type - vous ne voulez pas savoir si l'objet en question est une liste, vous voulez savoir si c'est une sorte de séquence ou si c'est un objet unique. Donc, essayez de l'utiliser comme une séquence.

Dites que vous voulez ajouter l'objet d'une séquence existante, ou si c'est une séquence d'objets, ajouter tous les

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

un truc avec ceci est si vous travaillez avec des cordes et/ou des séquences de cordes - c'est délicat, car une corde est souvent considérée comme un seul objet, mais c'est aussi une séquence de caractères. Pire que ça, car c'est vraiment une séquence de cordes simples.

j'ai l'habitude de choisir de concevoir mon API pour qu'elle n'accepte qu'une seule valeur ou une séquence - cela facilite les choses. Il n'est pas difficile de mettre un [ ] autour de votre valeur unique quand vous les transmettre en cas de besoin.

(bien que cela puisse causer des erreurs avec les chaînes, car elles ressemblent à des séquences (sont).)

3
répondu Chris Barker 2017-11-11 13:36:15

les annotations de type Python sont maintenant chose faite. Jetez un oeil à mypy

0
répondu Sheena 2018-10-05 08:54:23

vous pouvez vérifier avec la ligne ci-dessous quel type de caractère la valeur donnée est:

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

chr_type("12)
-6
répondu Venkatesan 2017-11-11 13:38:16