1266 votes

En Python, comment puis-je déterminer si un objet est itératif?

Est-il une méthode comme isiterable? La seule solution que j'ai trouvé pour l'instant est d'appeler

hasattr(myObj, '__iter__')

Mais je ne suis pas sûr de la façon infaillible de ce qui est.

939voto

miku Points 63392
  1. La vérification de __iter__ fonctionne sur les types de séquence, mais il ne pourrait pas sur, par exemple, des chaînes de caractères. Je voudrais savoir le droit de réponse trop, jusqu'alors, ici, c'est une possibilité (qui serait de travailler sur des chaînes de caractères):

    try:
        some_object_iterator = iter(some_object)
    except TypeError, te:
        print some_object, 'is not iterable'
    

    L' iter contrôles intégrés pour l' iter méthode ou, dans le cas des chaînes de la getitem méthode. Pour vérifier si un objet est la liste des "like" et pas "chaîne comme" la clé est les attributs __getitem__ et __iter__:

     In [9]: hasattr([1,2,3,4], '__iter__')
     Out[9]: True
     In [11]: hasattr((1,2,3,4), '__iter__')
     Out[11]: True
     In [12]: hasattr(u"hello", '__iter__')
     Out[12]: False
     In [14]: hasattr(u"hello", '__getitem__')
     Out[14]: True
    
  2. Un autre général pythonic approche est de supposer un objet iterable, puis échouer normalement si il ne fonctionne pas sur l'objet donné. Le python glossaire:

    Pythonic style de programmation qui détermine un type de l'objet par l'inspection de sa méthode ou d'un attribut signature plutôt que par la relation explicite à un certain type d'objet ("Si ça ressemble à un canard et les charlatans comme un canard, il doit etre un canard.") En mettant l'accent sur les interfaces plutôt que des types spécifiques, bien conçus code améliore sa souplesse en permettant polymorphe de substitution. Duck-typing évite de tests à l'aide de type() ou isinstance(). Au lieu de cela, il utilise habituellement le l'aeap (plus Facile de Demander Pardon que la Permission) style de programmation.

    ...

    try:
       _ = (e for e in my_object)
    except TypeError:
       print my_object, 'is not iterable'
    
  3. L' collections module fournit certaines classes de base abstraites, qui permettent de poser des classes ou des instances si elles offrent la fonctionnalité particulière, par exemple:

    import collections
    
    if isinstance(e, collections.Iterable):
        # e is iterable
    

645voto

Georg Schölly Points 63123

Duck-typing

try:
    iterator = iter(theElement)
except TypeError:
    # not iterable
else:
    # iterable

# for obj in iterator:
#     pass

La vérification de Type

Utiliser les Classes de Base Abstraites. Il leur faut au moins la version 2.6 de Python et de ne travailler que pour les nouvelles classes de style.

import collections

if isinstance(theElement, collections.Iterable):
    # iterable
else:
    # not iterable

33voto

jldupont Points 31331

Ce n'est pas suffisant: l'objet renvoyé par __iter__ doit mettre en œuvre l'itération protocole (c - next méthode). Voir la section correspondante dans la documentation.

En Python, une bonne pratique consiste à "essayer pour voir" au lieu de "vérification".

21voto

badp Points 5036
try:
  #treat object as iterable
except TypeError, e:
  #object is not actually iterable

Ne pas exécuter des vérifications pour voir si votre canard est vraiment un canard pour voir si il est itératif ou pas, la traiter comme si elle était et de se plaindre, si ce n'était pas le cas.

15voto

Vlad Points 200

La meilleure solution que j'ai trouvé jusqu'à présent:

hasattr(obj, '__contains__')

qui, fondamentalement, vérifie si l'objet implémente l' in de l'opérateur.

Avantages (aucune des autres solutions a tous les trois):

  • c'est une expression (fonctionne comme un lambda, par opposition à la try...catch variante)
  • il est (devrait être) mis en œuvre par tous les iterables, y compris les chaînes de caractères (par opposition à l' __iter__)
  • fonctionne sur n'importe quel Python >= 2.5

Notes:

  • le Python de la philosophie de "demander pardon, pas la permission" ne fonctionne pas bien lorsque par exemple dans une liste que vous avez à la fois iterables et non iterables et vous avez besoin pour traiter chaque élément différemment en fonction de son type (traitement de iterables sur essayez et non iterables sur l'exception serait le travail, mais il serait butt-ugly et trompeuses)
  • les solutions à ce problème qui tentent de réellement effectuer une itération sur l'objet (par exemple, [x for x in obj]) pour vérifier si il est itératif peut induire des pénalités pour les grandes iterables (surtout si vous avez juste besoin les premiers éléments de l'itératif, par exemple) et doit être évitée

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X