En Python, comment déterminer si un objet est itérable?
y a-t-il une méthode comme isiterable
? La seule solution que j'ai trouvée jusqu'à présent est d'appeler
hasattr(myObj, '__iter__')
mais je ne suis pas sûr à quel point cela est stupide.
19 réponses
-
vérifier pour
__iter__
fonctionne sur les types de séquence, mais il manquerait par exemple sur les chaînes en Python 2 . Je voudrais savoir la bonne réponse aussi, d'ici là, voici une possibilité (qui fonctionnerait sur les cordes, aussi):try: some_object_iterator = iter(some_object) except TypeError as te: print some_object, 'is not iterable'
le
iter
contrôle intégré pour la méthode__iter__
ou dans le cas de Chaînes la méthode__getitem__
. -
Une autre approche générale de pythonic est de supposer un itérable, puis d'échouer gracieusement si elle ne fonctionne pas sur l'objet donné. Le glossaire Python:
le style de programmation pythonique qui détermine le type d'un objet par l'inspection de sa méthode ou de sa signature d'attribut plutôt que par une relation explicite avec un objet de type ("S'il ressemble à un canard et des charlatans comme un canard , il doit être un canard .") En mettant l'accent sur les interfaces plutôt que sur les types spécifiques, un code bien conçu améliore sa flexibilité en permettant la substitution polymorphe. Duck-typing évite de tests à l'aide de type() ou isinstance(). au lieu de cela, il emploie typiquement le style de programmation EAFP (plus facile de demander pardon que la Permission).
...
try: _ = (e for e in my_object) except TypeError: print my_object, 'is not iterable'
-
Le
collections
module fournit quelques classes de base abstraites, qui permettent de demander des classes ou des instances si elles fournissent une fonctionnalité particulière, par exemple:import collections if isinstance(e, collections.Iterable): # e is iterable
cependant, cela ne vérifie pas les classes qui sont itérables par
__getitem__
.
Duck typing
try:
iterator = iter(theElement)
except TypeError:
# not iterable
else:
# iterable
# for obj in iterator:
# pass
contrôle de Type
utiliser les classes de base abstraites . Ils ont besoin d'au moins Python 2.6 et ne fonctionnent que pour les classes de nouveau style.
from collections.abc import Iterable # import directly from collections for Python < 3.3
if isinstance(theElement, Iterable):
# iterable
else:
# not iterable
cependant, iter()
est un peu plus fiable comme décrit par la documentation :
Vérification
isinstance(obj, Iterable)
détecte les classes qui sont enregistré comme Itérables ou qui ont une méthode__iter__()
, mais il ne détecte pas les classes qui itèrent avec le__getitem__()
méthode. Le seul moyen fiable de déterminer si un objet est itérable est d'appeleriter(obj)
.
je voudrais apporter un peu plus de lumière sur l'interaction de iter
, __iter__
et __getitem__
et ce qui se passe derrière les rideaux. Armé de cette connaissance, vous serez en mesure de comprendre pourquoi le mieux que vous pouvez faire est
try:
iter(maybe_iterable)
print('iteration will probably work')
except TypeError:
print('not iterable')
je vais énumérer les faits d'abord et puis suivre avec un rappel rapide de ce qui se passe quand vous employez une boucle for
en python, suivie d'une discussion pour illustrer les faits.
faits
-
vous pouvez obtenir un itérateur de n'importe quel objet
o
en appelantiter(o)
si au moins une des conditions suivantes est vraie:
a)o
a une méthode__iter__
qui renvoie un objet itérateur. Un itérateur est tout objet avec une méthode__iter__
et__next__
(Python 2:next
).
b)o
a une méthode__getitem__
. -
contrôle pour une instance de
Iterable
ouSequence
, ou contrôle pour la l'attribut__iter__
n'est pas suffisant. -
si un objet
o
ne met en œuvre que__getitem__
, mais pas__iter__
,iter(o)
construira un itérateur qui tente de récupérer des éléments deo
par indice entier, à partir de l'indice 0. L'itérateur attrapera n'importe quelIndexError
(mais aucune autre erreur) qui est soulevé et puis soulèveStopIteration
lui-même. -
dans le sens le plus général, il n'y a aucun moyen de vérifier si l'itérateur retourné par
iter
est sain d'autre que de l'essayer. -
si un objet
o
met en œuvre__iter__
, la fonctioniter
assurer que l'objet retourné par__iter__
est un itérateur. Il n'y a pas de vérification générale si un objet ne met en œuvre que__getitem__
. -
__iter__
qui l'emporte. Si un objeto
met en œuvre à la fois__iter__
et__getitem__
,iter(o)
appellera__iter__
. -
si vous voulez rendre vos propres objets itérables, Toujours mettre en œuvre la méthode
__iter__
.
"1519190920 des" boucles "de 15191420920"
afin de suivre, vous avez besoin d'une compréhension de ce qui se passe lorsque vous employez une boucle for
en Python. Hésitez pas à aller directement à la section suivante si vous savez déjà.
lorsque vous utilisez for item in o
pour un objet itérable o
, Python appelle iter(o)
et attend un objet itérateur comme valeur de retour. Un itérateur est tout objet qui met en œuvre une méthode __next__
(ou next
en Python 2) et une méthode __iter__
.
par convention, la méthode __iter__
d'un itérateur doit retourner l'objet lui-même (c.-à-d. return self
). Python appelle alors next
sur l'itérateur jusqu'à ce que StopIteration
soit soulevé. Tout cela se produit implicitement, mais la démonstration suivante le rend visible:
import random
class DemoIterable(object):
def __iter__(self):
print('__iter__ called')
return DemoIterator()
class DemoIterator(object):
def __iter__(self):
return self
def __next__(self):
print('__next__ called')
r = random.randint(1, 10)
if r == 5:
print('raising StopIteration')
raise StopIteration
return r
itération sur un DemoIterable
:
>>> di = DemoIterable()
>>> for x in di:
... print(x)
...
__iter__ called
__next__ called
9
__next__ called
8
__next__ called
10
__next__ called
3
__next__ called
10
__next__ called
raising StopIteration
Discussion et illustrations
sur les points 1 et 2: Obtenir un itérateur et des contrôles peu fiables
considérer la classe suivante:
class BasicIterable(object):
def __getitem__(self, item):
if item == 3:
raise IndexError
return item
Appel iter
avec une instance de BasicIterable
retourne un itérateur sans aucun problème parce que BasicIterable
met en œuvre __getitem__
.
>>> b = BasicIterable()
>>> iter(b)
<iterator object at 0x7f1ab216e320>
cependant, il est important de noter que b
n'a pas l'attribut __iter__
et n'est pas considéré comme une instance de Iterable
ou Sequence
:
>>> from collections import Iterable, Sequence
>>> hasattr(b, '__iter__')
False
>>> isinstance(b, Iterable)
False
>>> isinstance(b, Sequence)
False
C'est pourquoi Fluent Python par Luciano Ramalho recommande d'appeler iter
et de gérer le potentiel TypeError
comme le moyen le plus précis de vérifier si un objet est itérable. Citant directement du livre:
depuis Python 3.4, la façon la plus précise de vérifier si un objet
x
est itérable est d'appeleriter(x)
et de gérer une exceptionTypeError
si ce n'est pas le cas. Ceci est plus exact que l'utilisation deisinstance(x, abc.Iterable)
, parce queiter(x)
considère également la méthode de l'héritage__getitem__
, tandis queIterable
ABC ne le fait pas.
au point 3: itération sur des objets qui ne fournissent que __getitem__
, mais pas __iter__
itérant sur une instance de BasicIterable
fonctionne comme prévu: Python
construit un itérateur qui essaie de récupérer des éléments par index, en commençant à zéro, jusqu'à ce qu'un IndexError
soit soulevé. La méthode __getitem__
de l'objet Démo renvoie simplement le item
qui a été fourni comme argument à __getitem__(self, item)
par l'itérateur retourné par iter
.
>>> b = BasicIterable()
>>> it = iter(b)
>>> next(it)
0
>>> next(it)
1
>>> next(it)
2
>>> next(it)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
notez que l'itérateur soulève StopIteration
quand il ne peut pas retourner l'article suivant et que le IndexError
qui est soulevé pour item == 3
est manipulé à l'interne. C'est pourquoi la boucle au-dessus d'un BasicIterable
avec une boucle for
fonctionne comme prévu:
>>> for x in b:
... print(x)
...
0
1
2
voici un autre exemple afin de ramener à la maison le concept de la façon dont l'itérateur retourné par iter
tente d'accéder aux articles par index. WrappedDict
n'hérite pas de dict
, ce qui signifie que les instances n'auront pas __iter__
la méthode.
class WrappedDict(object): # note: no inheritance from dict!
def __init__(self, dic):
self._dict = dic
def __getitem__(self, item):
try:
return self._dict[item] # delegate to dict.__getitem__
except KeyError:
raise IndexError
notez que les appels à __getitem__
sont délégués à dict.__getitem__
pour lequel la notation à crochets est simplement un raccourci.
>>> w = WrappedDict({-1: 'not printed',
... 0: 'hi', 1: 'StackOverflow', 2: '!',
... 4: 'not printed',
... 'x': 'not printed'})
>>> for x in w:
... print(x)
...
hi
StackOverflow
!
aux points 4 et 5: iter
vérifie l'existence d'un itérateur lorsqu'il appelle __iter__
:
quand iter(o)
est appelé pour un objet o
, iter
fera en sorte que le retour la valeur de __iter__
, si la méthode est présent, est un itérateur. Cela signifie que l'objet retourné
doit implémenter __next__
(ou next
en Python 2) et __iter__
. iter
ne peut pas effectuer de contrôles de santé mentale pour les objets qui
fournir __getitem__
, parce qu'il n'a aucun moyen de vérifier si les éléments de l'objet sont accessibles par un index entier.
class FailIterIterable(object):
def __iter__(self):
return object() # not an iterator
class FailGetitemIterable(object):
def __getitem__(self, item):
raise Exception
noter que la construction d'un itérateur à partir des instances FailIterIterable
échoue immédiatement, en construisant un itérateur de FailGetItemIterable
réussit, mais lancera une Exception sur le premier appel à __next__
.
>>> fii = FailIterIterable()
>>> iter(fii)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: iter() returned non-iterator of type 'object'
>>>
>>> fgi = FailGetitemIterable()
>>> it = iter(fgi)
>>> next(it)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/path/iterdemo.py", line 42, in __getitem__
raise Exception
Exception
Sur le point 6: __iter__
gagne
celui-ci est simple. Si un objet met en œuvre __iter__
et __getitem__
, iter
appellera __iter__
. Considérons la classe suivante
class IterWinsDemo(object):
def __iter__(self):
return iter(['__iter__', 'wins'])
def __getitem__(self, item):
return ['__getitem__', 'wins'][item]
et le sortie en boucle sur une instance:
>>> iwd = IterWinsDemo()
>>> for x in iwd:
... print(x)
...
__iter__
wins
Sur le point 7: votre objet iterable les classes à mettre en œuvre __iter__
vous pourriez vous demander pourquoi la plupart des séquences bâties comme list
implémentent une méthode __iter__
alors que __getitem__
serait suffisant.
class WrappedList(object): # note: no inheritance from list!
def __init__(self, lst):
self._list = lst
def __getitem__(self, item):
return self._list[item]
après tout, itération sur les instances de la classe ci-dessus, que les délégués appelle à __getitem__
à list.__getitem__
(à l'aide de la notation crochets), fonctionnera très bien:
>>> wl = WrappedList(['A', 'B', 'C'])
>>> for x in wl:
... print(x)
...
A
B
C
les raisons pour lesquelles vos itérables personnalisés devraient implémenter __iter__
sont les suivantes:
- si vous implémentez
__iter__
, les instances seront considérées comme itérables, etisinstance(o, collections.Iterable)
retourneraTrue
. - Si l'objet renvoyé par
__iter__
n'est pas un itérateur,iter
sera échouer immédiatement et élever uneTypeError
. - la manipulation spéciale de
__getitem__
existe pour des raisons de rétrocompatibilité. Citant à nouveau de Fluent Python:
C'est pourquoi toute séquence Python est itérable: ils implémentent tous
__getitem__
. Effectivement, les séquences standard mettent aussi en œuvre__iter__
, et la vôtre devrait aussi, parce que le la manipulation spéciale de__getitem__
existe pour l'arrière des raisons de compatibilité et peut être disparu dans l'avenir (même si elle n'est pas déconseillée pendant que j'écris ceci).
ce n'est pas suffisant: l'objet retourné par __iter__
doit implémenter le protocole d'itération (c'est-à-dire la méthode next
). Voir la section pertinente de la" documentation 151930920 .
en Python, une bonne pratique est d '" essayer de voir "au lieu de"vérifier".
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.
la meilleure solution que j'ai trouvée jusqu'à présent:
hasattr(obj, '__contains__')
qui vérifie essentiellement si l'objet implémente l'opérateur in
.
avantages (aucune des autres solutions n'a les trois):
- c'est une expression (fonctionne comme un lambda , par opposition à la essayer...sauf variante)
- il est (devrait être) mis en œuvre par tous les iterables, y compris chaînes (par opposition à
__iter__
) - fonctionne sur N'importe quel Python > = 2.5
Notes:
- la philosophie Python de "demander pardon, pas de permission" ne fonctionne pas bien lorsque, par exemple, dans une liste, vous avez à la fois des itérables et des non-itérables et que vous devez traiter chaque élément différemment selon son type (en traitant les itérables sur try et non-itérables sur sauf serait travail, mais il paraîtrait butt-laid et trompeuse)
- les solutions à ce problème qui tentent de réellement itérer au-dessus de l'objet (par exemple [x pour x dans obj]) pour vérifier s'il est itérable peut induire des pénalités de performance significatives pour les grandes itérables (surtout si vous avez juste besoin des premiers éléments de l'itérable, par exemple) et doit être évitée
en Python <= 2.5, vous ne pouvez pas et ne devriez pas - iterable était une interface" informelle".
mais depuis Python 2.6 et 3.0, vous pouvez tirer parti de la nouvelle infrastructure ABC (abstract base class) avec quelques ABC intégrés qui sont disponibles dans le module collections:
from collections import Iterable
class MyObject(object):
pass
mo = MyObject()
print isinstance(mo, Iterable)
Iterable.register(MyObject)
print isinstance(mo, Iterable)
print isinstance("abc", Iterable)
Maintenant, si cela est souhaitable ou fonctionne réellement, c'est juste une question de conventions. Comme vous pouvez le voir, vous can enregistrer un non-itérable objet Itérable - et il déclenche une exception à l'exécution. Par conséquent, isinstance acquiert un" nouveau "sens - il vérifie simplement la compatibilité de type" déclaré", ce qui est une bonne façon d'aller en Python.
par contre, si votre objet ne satisfait pas l'interface dont vous avez besoin, que ferez-vous? Prenons l'exemple suivant:
from collections import Iterable
from traceback import print_exc
def check_and_raise(x):
if not isinstance(x, Iterable):
raise TypeError, "%s is not iterable" % x
else:
for i in x:
print i
def just_iter(x):
for i in x:
print i
class NotIterable(object):
pass
if __name__ == "__main__":
try:
check_and_raise(5)
except:
print_exc()
print
try:
just_iter(5)
except:
print_exc()
print
try:
Iterable.register(NotIterable)
ni = NotIterable()
check_and_raise(ni)
except:
print_exc()
print
si l'objet ne satisfait pas ce que vous attendez, vous lancez juste une erreur de typographie, mais si L'ABC approprié a été enregistrée, votre chèque est inutile. Au contraire, si la méthode __iter__
est disponible, Python reconnaîtra automatiquement l'objet de cette classe comme étant itérable.
donc, si vous attendez juste un itérable, itérez-le et oubliez-le. D'un autre côté, si vous avez besoin de faire des choses différentes selon le type d'entrée, vous pourriez trouver L'infrastructure ABC assez utile.
vous pourriez essayer ceci:
def iterable(a):
try:
(x for x in a)
return True
except TypeError:
return False
si nous pouvons faire un générateur qui itère au-dessus (mais ne jamais utiliser le générateur de sorte qu'il ne prend pas de place), il est itérable. On dirait un truc du genre" duh". Pourquoi devez-vous déterminer si une variable est itérable en premier lieu?
selon le Python 2 Glossary , les itérables sont
tous les types de séquence (tels que
list
,str
, ettuple
) et certains types de non-séquence commedict
etfile
et les objets de n'importe quelle classe que vous définissez avec une méthode__iter__()
ou__getitem__()
. Iterables peut être utilisé dans une boucle for et dans beaucoup d'autres endroits où une séquence est nécessaire (zip(), map(), ...). Lorsqu'un objet itérable est passé comme argument à la fonction intégrée d'iter(), elle renvoie un itérateur sur l'objet.
bien sûr, étant donné le style de codage général pour Python basé sur le fait qu'il est "plus facile de demander le pardon que la permission.", l'attente générale est d'utiliser des
try:
for i in object_in_question:
do_something
except TypeError:
do_something_for_non_iterable
mais si vous avez besoin de le vérifier explicitement, vous pouvez tester pour un itérable par hasattr(object_in_question, "__iter__") or hasattr(object_in_question, "__getitem__")
. Vous devez vérifier pour les deux, parce que str
s n'ont pas une méthode __iter__
(du moins pas en Python 2, mais en Python 3) et parce que les objets generator
n'ont pas de méthode __getitem__
.
je trouve souvent commode, à l'intérieur de mes scripts, de définir une fonction iterable
.
(Incorpore maintenant la simplification suggérée par Alfe):
import collections
def iterable(obj):
return isinstance(obj, collections.Iterable):
ainsi vous pouvez tester si n'importe quel objet est itérable dans la forme très lisible
if iterable(obj):
# act on iterable
else:
# not iterable
comme vous le feriez avec la fonction callable
151970920"
modifier: si vous avez numpy installé, vous pouvez simplement faire: à partir de numpy import iterable
,
qui est tout simplement quelque chose comme
def iterable(obj):
try: iter(obj)
except: return False
return True
si vous n'avez pas de numpy, vous pouvez simplement implémenter ce code, ou celui ci-dessus.
depuis Python 3.5 vous pouvez utiliser le module Dactylographie de la bibliothèque standard pour les choses liées au type:
from typing import Iterable
...
if isinstance(my_item, Iterable):
print(True)
def is_iterable(x):
try:
0 in x
except TypeError:
return False
else:
return True
cela dira oui à toutes sortes d'objets itérables, mais il dira non aux chaînes en Python 2 . (C'est ce que je veux par exemple quand une fonction récursive pourrait prendre une chaîne ou un conteneur de chaînes. Dans cette situation, demander pardon peut conduire à obfuscode, et il est préférable de demander la permission d'abord.)
import numpy
class Yes:
def __iter__(self):
yield 1;
yield 2;
yield 3;
class No:
pass
class Nope:
def __iter__(self):
return 'nonsense'
assert is_iterable(Yes())
assert is_iterable(range(3))
assert is_iterable((1,2,3)) # tuple
assert is_iterable([1,2,3]) # list
assert is_iterable({1,2,3}) # set
assert is_iterable({1:'one', 2:'two', 3:'three'}) # dictionary
assert is_iterable(numpy.array([1,2,3]))
assert is_iterable(bytearray("not really a string", 'utf-8'))
assert not is_iterable(No())
assert not is_iterable(Nope())
assert not is_iterable("string")
assert not is_iterable(42)
assert not is_iterable(True)
assert not is_iterable(None)
beaucoup d'autres stratégies ici diront oui aux cordes. Utiliser si qu'est ce que vous voulez.
import collections
import numpy
assert isinstance("string", collections.Iterable)
assert isinstance("string", collections.Sequence)
assert numpy.iterable("string")
assert iter("string")
assert hasattr("string", '__getitem__')
Note: is_iterable() dira oui aux chaînes de type bytes
et bytearray
.
-
bytes
les objets en Python 3 sont itérablesTrue == is_iterable(b"string") == is_iterable("string".encode('utf-8'))
il n'y a pas un tel type en Python 2. -
bytearray
les objets en Python 2 et 3 sont itérablesTrue == is_iterable(bytearray(b"abc"))
L'O. P. hasattr(x, '__iter__')
approche va dire oui pour les chaînes de caractères en Python 3 et non en Python 2 (Peu importe si ''
ou b''
ou u''
). Merci à @LuisMasuelli d'avoir remarqué que vous tomberez aussi sur un buggy __iter__
.
la manière la plus simple, en respectant le Duck typing du Python, est d'attraper l'erreur (Python sait parfaitement ce qu'il attend d'un objet pour devenir un itérateur):
class A(object):
def __getitem__(self, item):
return something
class B(object):
def __iter__(self):
# Return a compliant iterator. Just an example
return iter([])
class C(object):
def __iter__(self):
# Return crap
return 1
class D(object): pass
def iterable(obj):
try:
iter(obj)
return True
except:
return False
assert iterable(A())
assert iterable(B())
assert iterable(C())
assert not iterable(D())
Notes :
- la distinction entre un objet non itérable ou un buggy
__iter__
a été implémentée, si le type d'exception est le même: de toute façon, vous ne serez pas en mesure pour effectuer une itération de l'objet. -
je pense que je comprends votre préoccupation: comment
callable
existe en tant que contrôle si je pouvais également compter sur duck dactylographier pour soulever unAttributeError
si__call__
n'est pas défini pour mon objet, mais ce n'est pas le cas pour la vérification itérable?Je ne sais pas la réponse, mais vous pouvez soit mettre en œuvre la fonction que j'AI (et d'autres utilisateurs) donné, ou tout simplement attraper l'exception dans votre code (votre mise en œuvre dans cette partie sera comme la fonction que j'ai écrite - assurez-vous juste d'isoler la création iterator du reste du code de sorte que vous pouvez capturer l'exception et la distinguer d'un autre
TypeError
.
le isiterable
func au code suivant renvoie True
si l'objet est itérable. si ce n'est pas itératif renvoie False
def isiterable(object_):
return hasattr(type(object_), "__iter__")
exemple
fruits = ("apple", "banana", "peach")
isiterable(fruits) # returns True
num = 345
isiterable(num) # returns False
isiterable(str) # returns False because str type is type class and it's not iterable.
hello = "hello dude !"
isiterable(hello) # returns True because as you know string objects are iterable
au lieu de vérifier l'attribut __iter__
, vous pouvez vérifier l'attribut __len__
, qui est implémenté par chaque composant de python itérable, y compris les chaînes.
>>> hasattr(1, "__len__")
False
>>> hasattr(1.3, "__len__")
False
>>> hasattr("a", "__len__")
True
>>> hasattr([1,2,3], "__len__")
True
>>> hasattr({1,2}, "__len__")
True
>>> hasattr({"a":1}, "__len__")
True
>>> hasattr(("a", 1), "__len__")
True
Aucun-les objets itérables ne mettraient pas en œuvre ceci pour des raisons évidentes. Cependant, on n'attrape pas définie par l'utilisateur iterables qui ne mettent pas en œuvre, ni générateur d'expressions, qui iter
. Cependant, cela peut être fait en une ligne, et l'ajout d'un une simple vérification de l'expression or
pour les générateurs réglerait ce problème. (Notez qu'écrire type(my_generator_expression) == generator
lancerait un NameError
. Référez-vous à ce réponse à la place.)
vous pouvez utiliser GeneratorType des types:
>>> import types >>> types.GeneratorType <class 'generator'> >>> gen = (i for i in range(10)) >>> isinstance(gen, types.GeneratorType) True
- - - réponse acceptée par utdemir
(ceci le rend utile pour vérifier si vous pouvez appeler len
sur l'objet cependant.)
il m'a toujours échappé pourquoi python a callable(obj) -> bool
mais pas iterable(obj) -> bool
...
c'est sûrement plus facile de faire hasattr(obj,'__call__')
même si c'est plus lent.
comme presque toutes les autres réponses recommandent d'utiliser try
/ except TypeError
, où les tests d'exceptions sont généralement considérés comme une mauvaise pratique dans n'importe quelle langue, voici une mise en œuvre de iterable(obj) -> bool
j'ai pris plus d'affection et d'utilisation souvent:
pour pour python 2, j'utiliserai un lambda juste pour augmenter mes performances...
(en python 3, peu importe ce que vous utilisez pour définir la fonction, def
a à peu près la même vitesse que lambda
)
iterable = lambda obj: hasattr(obj,'__iter__') or hasattr(obj,'__getitem__')
notez que cette fonction s'exécute plus rapidement pour les objets avec __iter__
puisqu'elle ne teste pas pour __getitem__
.
la plupart des objets itérables doivent s'appuyer sur __iter__
lorsque des objets spéciaux revenir à __getitem__
, bien que ce soit est nécessaire pour qu'un objet soit itératif.
(et puisqu'il s'agit d'une norme, elle affecte également les objets C)
mis à part l'essai régulier et sauf, vous pouvez exécuter l'aide.
temp= [1,2,3,4]
help(temp)
aide donnerait toutes les méthodes qui pourraient être exécutées sur cet objet(il pourrait être n'importe quel objet et peut ne pas être une liste comme par exemple), qui est temp dans ce cas.
Note: Ce serait quelque chose que vous feriez manuellement.