2010-05-26 7 views
22

Tengo una función de Python que acepta varios argumentos de cadena def foo(a, b, c): y los concatena en una cadena. Quiero iterar sobre todos los argumentos de funciones para comprobar que no son ninguno. ¿Cómo se puede hacer? ¿Hay alguna manera rápida de convertir None a ""?Cómo iterar sobre los argumentos de la función

Gracias.

Respuesta

27

locals() puede ser su amigo aquí si lo llama primero en su función.

Ejemplo 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': {...}} 

Ejemplo 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 

respuesta:

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

actualización:

destacado 'Ejemplo 1' para que tengamos un poco de trabajo extra para hacer si el orden de los argumentos es importante como el devuelto por dictlocals() (o vars()) es desordenada. La función anterior tampoco trata los números con mucha gracia. Así que aquí hay un par de mejoras:

>>> 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, creo que '* args' es el camino a seguir aquí ... ¿y si quieres concatenar dieciséis cuerdas? Solo quería mostrar que era posible en Python usando la firma de función proporcionada :-) – Johnsyweb

+0

en lugar de los locales, también puedes usar vars(). – extraneon

+0

@extraneon Gracias por el consejo. 'locals()' parece comportarse igual que 'vars()' sin argumentos en este caso. – Johnsyweb

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

si se está uniendo en una cadena vacía, sólo podía hacer ''.join(i for i in args if i is not None)

+0

¿Qué pasa si todos los argumentos se declaran explícitamente? Como en def foo (a, b, c): – jackhab

+0

@Jack: redefinir su función. Esa sería la opción más fácil. Si tiene pocos argumentos, podría ponerlos en una tupla. – SilentGhost

+1

Pero esto hace que el código sea menos legible – jackhab

-5

me gustaría utilizar SED/s Ninguno // g, pero eso no es en Python, pero es probable que pueda utilizar OS. popen() para hacer eso.

+1

¿Qué pasa si SilentGhosts en Windows ... ..not v pythonic .... :-) –

+2

Creo que 'None' significa el objeto python' None' not the literal string '" None "' –

2

Se puede utilizar el módulo de inspeccionar y definir una función de esa manera:

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}) 

en argspec hay toda la información que necesita para realizar cualquier operación con el argumento pasado.

Para concatenar la cadena es suficiente utilizar la información recibida arg:

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

Como referencia: http://docs.python.org/library/inspect.html#inspect.getargvalues

0

¿Es esta tal vez lo que desea?

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() 

Aviso el uso de vars(), que devuelve un diccionario.

Cuestiones relacionadas