variable - Quelle est la manière canonique de vérifier le type en Python?




type() python (6)

Quel est le meilleur moyen de vérifier si un objet donné est d'un type donné? Que diriez-vous 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 une str ?


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.

Je voudrais simplement appeler les méthodes requises sur votre objet et attraper 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.

Je l'ai beaucoup utilisé lors de l'obtention de données sur le web avec urllib2.urlopen() qui retourne un fichier comme objet. Cela peut à son tour être passé à presque n'importe quelle méthode qui lit à partir d'un fichier, car il implémente la même méthode read() qu'un vrai fichier.

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


La façon la plus pythonique de vérifier le type d'un objet est ... de ne pas le vérifier.

Puisque Python encourage Duck Typing , vous devriez simplement essayer d'utiliser les méthodes de l'objet de la façon dont vous voulez les utiliser. Donc, si votre fonction recherche un objet fichier inscriptible, ne vérifiez pas qu'il s'agit d'une sous-classe de file , essayez simplement 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.


Pour vérifier si o est une instance de str ou une sous-classe de str (ce serait la façon "canonique"):

if isinstance(o, str):

Pour vérifier si le type de o est exactement str :

if type(o) is str:

Ce qui suit fonctionne également, et peut être utile dans certains cas:

if issubclass(type(o), str):

if type(o) in ([str] + str.__subclasses__()):

Voir Fonctions intégrées dans la Référence de la bibliothèque Python pour des informations pertinentes.

Une note de plus: dans ce cas, vous pouvez réellement utiliser:

if isinstance(o, basestring):

parce que cela va aussi capturer les chaînes Unicode ( unicode n'est pas une sous-classe de str , les deux str et unicode sont des sous-classes de basestring ).

Alternativement, isinstance accepte un tuple de classes. Cela retournera True si x est une instance de n'importe quelle sous-classe de (str, unicode):

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

Une fois la question posée et la réponse obtenue, les astuces de type ont été ajoutées à Python . Les astuces de type en Python permettent de vérifier les types mais de façon très différente des langages statiquement typés. Les indications de type en Python associent les types d'arguments attendus avec les fonctions en tant que données accessibles à l'exécution associées aux fonctions, ce qui permet de vérifier les types. Exemple de syntaxe d'indice de type:

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 provoque pas d'erreur 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 devrez peut-être installer mypy partir de votre gestionnaire de paquets. Je ne pense pas qu'il soit fourni avec CPython mais semble avoir un certain niveau de "officialité".)

La vérification de type de cette manière est différente de la vérification de type dans les langages compilés statiquement typés. 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 sur le fait que cela arrive à chaque occasion. Les vérifications de type explicites peuvent également être plus restrictives que nécessaire et provoquer des erreurs inutiles (par exemple, l'argument doit-il 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 peut détecter des erreurs plus tôt et donner des messages d'erreur plus clairs que le typage de canard. Les exigences exactes d'un type de canard ne peuvent être exprimées qu'avec une documentation externe (espérons-le, c'est complet et précis) et les erreurs de types incompatibles peuvent se produire loin de leur origine.

Les indices de type 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 pendant l'exécution du code habituel.

Le package de typing propose des variables de type pouvant être utilisées dans les indications de type pour exprimer les comportements nécessaires sans nécessiter de types particuliers. Par exemple, il inclut des variables telles Iterable et Callable pour les indices afin de spécifier le besoin de n'importe quel type avec ces comportements.

Tandis que les astuces de type sont la façon la plus pythonique de vérifier les types, il est souvent encore plus Pythonic de ne pas vérifier les types du tout et de compter sur le typage du canard. Les conseils de type sont relativement nouveaux et le jury est toujours sur quand ils sont la solution la plus Pythonic. Une comparaison relativement non controversée mais très générale: Les astuces de type fournissent une forme de documentation qui peut être appliquée, permettent au code de générer des erreurs plus tôt et plus faciles à comprendre, peuvent intercepter des erreurs que le typage du canard ne peut pas et peuvent être vérifiées statiquement. sens mais c'est encore en dehors de l'exécution). D'un autre côté, le typage du canard a longtemps été la méthode Pythonienne, il n'impose pas le surcoût cognitif du typage statique, il est moins verbeux, il accepte tous les types viables et ensuite certains.


Vous pouvez vérifier avec la ligne ci-dessous pour vérifier 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)

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

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







types