Rappelez-vous qu'en Python on veut utiliser "duck typing". Donc, tout ce qui agit comme une liste peut être considérée comme une liste. Donc, ne pas vérifier le type d'une liste, il suffit de voir si elle agit comme une liste.
Mais les chaînes de loi comme une liste trop, et souvent ce n'est pas ce que nous voulons. Il y a des moments où il est même un problème! Donc, vérifier explicitement pour une chaîne de caractères, mais ensuite utiliser duck-typing.
Voici une fonction que j'ai écrit pour le plaisir. C'est une version spéciale de l' repr()
qui imprime toute la séquence dans les crochets ('<', '>').
def srepr(arg):
if isinstance(arg, basestring): # Python 3: isinstance(arg, str)
return repr(arg)
try:
return '<' + ", ".join(srepr(x) for x in arg) + '>'
except TypeError: # catch when for loop fails
return repr(arg) # not a sequence so just return repr
C'est propre et élégant, ensemble. Mais qu'est-ce que isinstance()
vérifier en train de faire là? C'est une sorte de hack. Mais il est essentiel.
Cette fonction s'appelle elle-même de manière récursive sur tout ce qui agit comme une liste. Si nous n'avons pas la poignée de la chaîne spécialement, alors il sera traité comme une liste, et de séparer les caractères un à un. Mais alors l'appel récursif voudrais essayer de traiter chaque caractère comme une liste, et cela fonctionne! Même une chaîne de caractères fonctionne comme une liste! La fonction serait de les garder sur l'appel lui-même de manière récursive jusqu'à ce débordement de pile.
Des fonctions comme celle-ci, qui dépendent de chaque appel récursif de casser le travail à faire, avoir spéciales aux chaînes--parce que vous ne pouvez pas briser une chaîne de caractères au-dessous du niveau d'une chaîne de caractères, et même une chaîne de caractères agit comme une liste.
Remarque: l' try
/except
est la façon la plus propre à exprimer nos intentions. Mais si ce code était en quelque sorte le temps critique, on peut vouloir le remplacer par une sorte de test pour voir si arg
est une séquence. Plutôt que de tester le type, nous devrions sans doute une analyse des comportements. Si il a un .strip()
méthode, c'est une chaîne, afin de ne pas les considérer comme une séquence; si, au contraire, il est indexable ou itératif, c'est une séquence:
def is_sequence(arg):
return (not hasattr(arg, "strip") and
hasattr(arg, "__getitem__") or
hasattr(arg, "__iter__"))
def srepr(arg):
if is_sequence(arg):
return '<' + ", ".join(srepr(x) for x in arg) + '>'
return repr(arg)
EDIT: j'ai d'abord écrit ci-dessus avec un chèque de __getslice__()
mais j'ai remarqué que dans l' collections
documentation du module, la méthode intéressante est l' __getitem__()
, ce qui fait sens, c'est la façon dont vous l'index d'un objet. Celui qui semble le plus fondamental qu' __getslice__()
j'ai donc changé le ci-dessus.