2010-05-26 6 views
22

J'ai une fonction Python acceptant plusieurs arguments de chaîne def foo(a, b, c): et les concaténant dans une chaîne. Je veux parcourir tous les arguments de la fonction pour vérifier qu'ils ne sont pas None. Comment cela peut-il être fait? Existe-t-il un moyen rapide de convertir None en ""?Comment faire une itération sur les arguments de fonction

Merci.

Répondre

27

locals() peut être votre ami ici si vous l'appelez la première chose dans votre fonction.

Exemple 1:

>>> def fun(a, b, c): 
...  d = locals() 
...  e = d 
...  print e 
...  print locals() 
... 
>>> fun(1, 2, 3) 
{'a': 1, 'c': 3, 'b': 2} 
{'a': 1, 'c': 3, 'b': 2, 'e': {...}, 'd': {...}} 

Exemple 2:

>>> def nones(a, b, c, d): 
...  arguments = locals() 
...  print 'The following arguments are not None: ', ', '.join(k for k, v in arguments.items() if v is not None) 
... 
>>> nones("Something", None, 'N', False) 
The following arguments are not None: a, c, d 

réponse:

>>> def foo(a, b, c): 
...  return ''.join(v for v in locals().values() if v is not None) 
... 
>>> foo('Cleese', 'Palin', None) 
'CleesePalin' 

Mise à jour:

« Exemple 1 » met en évidence que nous avons un travail supplémentaire à faire si l'ordre de vos arguments est important que le dict retourné par locals() (ou vars()) est non ordonnée. La fonction ci-dessus ne traite pas non plus les nombres avec beaucoup de grâce. Alors, voici quelques raffinements:

>>> def foo(a, b, c): 
...  arguments = locals() 
...  return ''.join(str(arguments[k]) for k in sorted(arguments.keys()) if arguments[k] is not None) 
... 
>>> foo(None, 'Antioch', 3) 
'Antioch3' 
+0

FWIW, je pense que' * args' est le chemin à parcourir ici ... et si vous voulez concaténer seize cordes? Je voulais juste montrer que c'était possible en Python en utilisant la signature de la fonction fournie :-) – Johnsyweb

+0

au lieu de locales, vous pouvez aussi utiliser vars(). – extraneon

+0

@extraneon Merci pour le conseil. 'locals()' semble se comporter de la même manière que 'vars()' sans argument dans ce cas. – Johnsyweb

15
def func(*args): 
    ' '.join(i if i is not None else '' for i in args) 

si vous vous joignez à une chaîne vide, vous pouvez simplement faire ''.join(i for i in args if i is not None)

+0

Et si tous les arguments étaient explicitement déclarés? Comme dans def foo (a, b, c): – jackhab

+0

@Jack: redéfinissez votre fonction. Ce serait l'option la plus facile. Si vous n'avez que peu d'arguments, vous pouvez les mettre dans un tuple. – SilentGhost

+1

Mais cela rend le code moins lisible – jackhab

-5

J'utiliseraient sed s/g Aucun //, mais ce n'est pas en python, mais vous pouvez probablement utiliser os. popen() pour le faire.

+1

Que faire si SilentGhosts sous Windows ... ..not v pythonic .... :-) –

+2

Je pense que 'None' signifie l'objet python' None' pas la chaîne littérale '' None '' –

2

Vous pouvez utiliser le inspectez module et définir une fonction comme:

import inspect 
def f(a,b,c): 
    argspec=inspect.getargvalues(inspect.currentframe()) 
    return argspec 
f(1,2,3) 
ArgInfo(args=['a', 'b', 'c'], varargs=None, keywords=None, locals={'a': 1, 'c': 3, 'b': 2}) 

dans argspec il y a toutes les informations dont vous avez besoin pour effectuer toute opération avec l'argument passé.

Pour concaténer la chaîne est suffisante pour utiliser les informations arg reçues:

def f(a,b,c): 
    argspec=inspect.getargvalues(inspect.currentframe()) 
    return ''.join(argspec.locals[arg] for arg in argspec.args) 

Pour référence: http://docs.python.org/library/inspect.html#inspect.getargvalues

0

Est-ce peut-être ce que vous voulez?

def foo(a, b, c): 
    "SilentGhost suggested the join" 
    ' '.join(i if i is not None else '' for i in vars().values()) 

def bar(a,b,c): 
    "A very usefull method!" 
    print vars() 
    print vars().values() 

Notez l'utilisation de vars(), qui retourne un dict.

Questions connexes