Pregunta

Tengo una función de Python en la que estoy haciendo un saneamiento de los parámetros de entrada:

def func(param1, param2, param3):
    param1 = param1 or ''
    param2 = param2 or ''
    param3 = param3 or ''

Esto satisface los argumentos que se pasan como Ninguno en lugar de cadenas vacías. ¿Existe una manera más fácil / más concisa de hacer un bucle alrededor de los parámetros de la función para aplicar dicha expresión a todos ellos? Mi función real tiene nueve parámetros.

¿Fue útil?

Solución

Esto parece ser un buen trabajo para un decorador. ¿Qué tal esto?

def sanitized(func):
    def sfunc(*args, **kwds):
        return func(*[arg or '' for arg in args],
                    **dict((k, v or '') for k,v in kwds.iteritems()))
    sfunc.func_name = func.func_name
    sfunc.func_doc = func.func_doc
    return sfunc

Usaría esto en su función así:

@sanitized
def func(param1, param2, param3):
    print param1, param2, param3

Entonces los parámetros serán reemplazados por la cadena vacía si son falsas:

>>> func('foo', None, 'spam')
foo  spam

(Tenga en cuenta que esto aún arruinará la firma de la función como lo señala Ned Batchelder en su respuesta. Para solucionarlo, puede usar módulo decorador de Michele Simionato : creo que solo necesitarías agregar un @decorator antes de la definición de sanitized )

Otros consejos

Podrías hacer alguna manipulación de la lista:

def func(param1, param2, param3):
    param1, param2, param3 = map(lambda x: x or '', (param1, param2, param3))

pero no estoy seguro de que sea mejor que solo escribir las nueve líneas, ya que una vez que llegas a los nueve parámetros, es una línea terriblemente larga.

Podrías cambiar la declaración de la función:

def func(*args):
    param1, param2, param3 = map(lambda x: x or '', args)

pero luego pierde la documentación que proviene de tener nombres de parámetros reales, así como la posibilidad de cambiar los valores predeterminados, etc. Y todavía tiene una línea bastante fea para desempaquetarlos.

Digo que escriba las nueve líneas, o cambie la función para que tenga menos parámetros: ¡de todos modos, nueve es bastante!

def func(x='', y='', z='hooray!'):
    print x, y, z

In [2]: f('test')
test  hooray!

In [3]: f('test', 'and')
test and hooray!

In [4]: f('test', 'and', 'done!')
test and done!
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top