61 votes

Comment puis-je savoir si une variable python est une chaîne ou une liste ?

J'ai une routine qui prend une liste de chaînes en paramètre, mais j'aimerais pouvoir passer une seule chaîne et la convertir en une liste d'une chaîne. Par exemple :

def func( files ):
    for f in files:
        doSomethingWithFile( f )

func( ['file1','file2','file3'] )

func( 'file1' ) # should be treated like ['file1']

Comment ma fonction peut-elle savoir si une chaîne de caractères ou une liste a été transmise ? Je sais qu'il existe un type mais existe-t-il un moyen plus "pythique" ?

43voto

Ayman Hourieh Points 39435
isinstance(your_var, basestring)

37voto

David Berger Points 5459

Eh bien, il n'y a rien d'impythique à vérifier le type. Cela dit, si vous êtes prêt à mettre une petite charge sur l'appelant :

def func( *files ):
    for f in files:
         doSomethingWithFile( f )

func( *['file1','file2','file3'] ) #Is treated like func('file1','file2','file3')
func( 'file1' )

Je dirais que c'est plus pythonique dans le sens où "l'explicite est meilleur que l'implicite". Ici, il y a au moins une reconnaissance de la part de l'appelant lorsque l'entrée est déjà sous forme de liste.

32voto

Dave Points 5879

Personnellement, je n'aime pas vraiment ce genre de comportement - il interfère avec la saisie des canards. On pourrait dire qu'il n'obéit pas au mantra "Explicit is better than implicit". Pourquoi ne pas utiliser la syntaxe varargs :

def func( *files ):
    for f in files:
        doSomethingWithFile( f )

func( 'file1', 'file2', 'file3' )
func( 'file1' )
func( *listOfFiles )

16voto

dbr Points 66401

Je dirais que la méthode la plus Python est de faire en sorte que l'utilisateur passe toujours une liste, même si elle ne contient qu'un seul élément. Cela rend vraiment évident func() peut prendre une liste de fichiers

def func(files):
    for cur_file in files:
        blah(cur_file)

func(['file1'])

Comme Dave l'a suggéré, vous pourriez utiliser le func(*files) mais je n'ai jamais aimé cette fonctionnalité, et il semble plus explicite ("l'explicite est meilleur que l'implicite") de simplement exiger une liste. Cela transforme également votre cas spécial (appel de func avec un seul fichier) dans le cas par défaut, car maintenant vous devez utiliser une syntaxe supplémentaire pour appeler func avec une liste..

Si vous voulez faire un cas spécial pour un argument qui est une chaîne, utilisez la fonction isinstance() intégré et comparer à basestring (qui à la fois str() y unicode() sont dérivés) par exemple :

def func(files):
    if isinstance(files, basestring):
        doSomethingWithASingleFile(files)
    else:
        for f in files:
            doSomethingWithFile(f)

Vraiment, je suggère d'exiger simplement une liste, même avec un seul fichier (après tout, cela ne nécessite que deux caractères supplémentaires !)

11voto

limscoder Points 1504
if hasattr(f, 'lower'): print "I'm string like"

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