Allez-y et utilisez isinstance
si vous en avez besoin. C'est un peu diabolique, car cela exclut les séquences personnalisées, les itérateurs et d'autres choses dont vous pourriez avoir besoin. Cependant, il faut parfois se comporter différemment si quelqu'un, par exemple, passe une chaîne de caractères. Dans ce cas, ma préférence irait à la vérification explicite de la présence de str
ou unicode
comme ça :
import types
isinstance(var, types.StringTypes)
N.B. Ne faites pas d'erreur types.StringType
pour types.StringTypes
. Ce dernier incorpore str
et unicode
objets.
Le site types
est considéré par beaucoup comme obsolète en faveur de la vérification directe du type de l'objet. Si vous préférez ne pas utiliser le module ci-dessus, vous pouvez vérifier explicitement le type de l'objet. str
et unicode
comme ceci :
isinstance(var, (str, unicode)):
Edit :
C'est encore mieux :
isinstance(var, basestring)
Montage final
Après l'un ou l'autre de ces cas, vous pouvez revenir à un comportement comme si vous obteniez une séquence normale, en laissant les non séquences soulever les exceptions appropriées.
Vous voyez que ce qui est "mauvais" dans la vérification du type n'est pas que vous souhaitiez vous comporter différemment pour un certain type d'objet, c'est que vous empêchez artificiellement votre fonction de faire la bonne chose avec des types d'objets inattendus qui, autrement, feraient la bonne chose. Si vous avez un fallback final qui n'est pas vérifié par type, vous supprimez cette restriction. Il convient de noter que trop de vérification de type est une odeur de code qui indique que vous pourriez vouloir faire un peu de refactoring, mais cela ne signifie pas nécessairement que vous devez l'éviter dès le départ.
77 votes
Il est un peu facile de rejeter le contrôle de type comme un mal. C'est une partie du langage. Si c'est si mauvais, quelqu'un devrait écrire un PEP pour le supprimer.
0 votes
Quel comportement voulez-vous avoir si vous obtenez un autre type de collection itérable (comme un ensemble ou une chaîne, par exemple) ?
4 votes
@Adam Crossland : "Ça fait partie de la langue." Tout comme la division par zéro. C'est évitable. Dans ce cas, sans information supplémentaire, c'est probablement complètement inutile. La plupart des vérifications de type en Python sont inutiles. Puisque pas tous est inutile, une vérification du type doit être présente. Mais cela ne signifie pas que c'est utile, précieux ou même une bonne idée.
12 votes
Vous dites donc qu'un certain type de contrôle est nécessaire, mais que malgré cela, il est inutile, sans valeur et une mauvaise idée. Désolé, ça n'a pas de sens.
19 votes
Le "XXX est mauvais" est un raccourci mal conçu et trompeur pour "la façon dont vous demandez à faire XXX suggère que vous ne comprenez pas quand il doit être utilisé, et vous voulez presque certainement autre chose". C'est très probablement le cas ici.
2 votes
Je ne l'ai pas rejeté en bloc comme étant mauvais. J'ai écrit un court essai pour dire quand c'est mal et quand c'est justifiable. Cet essai peut être très diversifié - bon, mauvais, clair, vague, agréable, ennuyeux - mais il ne s'agit pas d'un rejet général de la technique.
2 votes
Veuillez noter que depuis le PEP 3119, isinstance est devenu plus correct. Grâce aux classes de base abstraites, isinstance est maintenant le moyen le plus correct de décider à coup sûr si une classe supportera des choses comme les protocoles généraux de collecte !
2 votes
De plus, il est souvent préférable d'avoir un système fail-fast pour des choses telles que les appels de méthode différés ; il devient très difficile de déboguer la raison pour laquelle un appel de méthode différé échoue par la suite. En python 3, il n'y a pas de "callable(x)" ; la manière correcte de vérifier si un objet donné est appelable sans l'appeler est de faire isinstance(obj, collections.abc.Callable).
0 votes
Comme je l'ai expliqué dans l'un des commentaires de la réponse, il est parfois nécessaire de savoir avec certitude qu'un conteneur est ordonné, et cela peut n'être possible que par une vérification de type (ou peut l'être dans certains cas),
getattr(obj, '__getitem__')
mais c'est moche). Lorsque l'ordre des éléments d'un objet conteneur a de l'importance, un algorithme qui ne vérifie pas cet aspect peut potentiellement générer des résultats différents selon l'exécution ! Je ne pense pas que la vérification de type soit un mal, car elle peut être essentielle.