En python, existe-t-il un moyen facile de savoir si quelque chose n'est pas une séquence? J'ai essayé de faire: if x is not sequence
mais python n'a pas aimé ça
iter(x)
lèvera une TypeError
si x
ne peut pas être itéré - mais cette vérification "accepte" les ensembles et les dictionnaires, bien qu'elle "rejette" d'autres non-séquences telles que None
et des nombres.
D'autre part, les chaînes (que la plupart des applications veulent considérer comme des "éléments individuels" plutôt que des séquences) sont en fait des séquences (donc, tout test, à moins que cela ne soit spécial pour les chaînes, va confirmer qu'ils le sont). Ainsi, ces simples contrôles ne suffisent souvent pas.
En Python 2.6 et supérieur, les classes de base abstraites ont été introduits et, parmi d’autres fonctionnalités puissantes, ils offrent un meilleur support systématique pour ce type de "contrôle de catégorie".
>>> import collections
>>> isinstance([], collections.Sequence)
True
>>> isinstance((), collections.Sequence)
True
>>> isinstance(23, collections.Sequence)
False
>>> isinstance('foo', collections.Sequence)
True
>>> isinstance({}, collections.Sequence)
False
>>> isinstance(set(), collections.Sequence)
False
Vous remarquerez que les chaînes sont encore considérées comme "une séquence" (puisqu'elles sont ), mais au moins vous obtenez des dict et des sets à l'écart. Si vous souhaitez exclure les chaînes de votre concept "séquences", vous pouvez utiliser collections.MutableSequence
(mais cela exclut également les n-uplets qui, comme les chaînes, sont des séquences, mais ne sont pas mutables), ou le font explicitement:
import collections
def issequenceforme(obj):
if isinstance(obj, basestring):
return False
return isinstance(obj, collections.Sequence)
Assaisonner au goût et servir chaud! -)
Je pense que l'extrait de code ci-dessous fait ce que vous voulez:
def is_sequence(obj):
return hasattr(type(obj), '__iter__')
La documentation Python 2.6.5 décrit les types de séquence suivants: chaîne, chaîne Unicode, liste, Tuple, tampon et xrange.
def isSequence(obj):
return type(obj) in [str, unicode, list, Tuple, buffer, xrange]
Pourquoi fais-tu ça? La manière habituelle ici est de demander un certain type de chose (une séquence ou un nombre ou un objet de type fichier, etc.), puis de l’utiliser sans rien vérifier. En Python, nous n'utilisons généralement pas de classes pour transporter des informations sémantiques, nous utilisons simplement les méthodes définies (cela s'appelle "typage de canard") Nous préférons également les API où nous savons exactement à quoi nous attendre. utilisez des arguments de mots clés, un prétraitement ou la définition d'une autre fonction si vous souhaitez modifier le fonctionnement d'une fonction.
Pour Python 3 et 2.6+, vous pouvez vérifier s'il s'agit d'une sous-classe de collections.Sequence
:
>>> import collections
>>> isinstance(myObject, collections.Sequence)
True
Dans Python 3.7, vous devez utiliser collections.abc.Sequence
(collections.Sequence
sera supprimé dans Python 3.8):
>>> import collections.abc
>>> isinstance(myObject, collections.abc.Sequence)
True
Toutefois, cela ne fonctionnera pas pour les séquences de type canard qui implémentent __len__()
et __getitem__()
mais ne font pas (comme elles devraient) la sous-classe collections.Sequence
. Mais cela fonctionnera pour tous les types de séquence Python intégrés: listes, n-uplets, chaînes, etc.
Bien que toutes les séquences soient itérables, elles ne le sont pas toutes (par exemple, les ensembles et les dictionnaires sont itératifs, mais pas les séquences). La vérification de hasattr(type(obj), '__iter__')
renverra True
pour les dictionnaires et les ensembles.