propias procedimientos por parametros opcionales omision funciones argumentos python python-2.7

python - procedimientos - Argumentos por defecto con*args y** kwargs



kwargs python 3 (5)

En Python 2.x (yo uso 2.7), ¿cuál es la forma correcta de usar argumentos por defecto con *args y **kwargs ?
He encontrado una pregunta sobre SO relacionada con este tema, pero eso es para Python 3 :
Llamar a una función de Python con * args, ** kwargs y argumentos opcionales / predeterminados

Allí, dicen que este método funciona:

def func(arg1, arg2, *args, opt_arg=''def_val'', **kwargs): #...

En 2.7, da como resultado un SyntaxError . ¿Hay alguna manera recomendada de definir tal función?
Lo hice funcionar de esta manera, pero creo que hay una solución más agradable.

def func(arg1, arg2, *args, **kwargs): opt_arg =''def_val'' if kwargs.__contains__(''opt_arg''): opt_arg = kwargs[''opt_arg''] #...


La sintaxis en la otra pregunta es solo python3.x y especifica solo argumentos de palabra clave. No funciona en python2.x.

Para python2.x, lo sacaría de kwargs:

def func(arg1, arg2, *args, **kwargs): opt_arg = kwargs.pop(''opt_arg'', ''def_val'')


Manteniéndome bastante cerca de su enfoque de solución al tratar de hacerlo más genérico y más compacto, le sugiero que considere algo como esto:

>>> def func(arg1, arg2, *args, **kwargs): ... kwargs_with_defaults = dict({''opt_arg'': ''def_val'', ''opt_arg2'': ''default2''}, **kwargs) ... #... ... return arg1, arg2, args, kwargs_with_defaults >>> func(''a1'', ''a2'', ''a3'', ''a5'', x=''foo'', y=''bar'') (''a1'', ''a2'', (''a3'', ''a5''), {''opt_arg2'': ''default2'', ''opt_arg'': ''def_val'', ''y'': ''bar'', ''x'': ''foo''}) >>> func(''a1'', ''a2'', ''a3'', ''a5'', opt_arg=''explicit_value'', x=''foo'', y=''bar'') (''a1'', ''a2'', (''a3'', ''a5''), {''opt_arg2'': ''default2'', ''opt_arg'': ''explicit_value'', ''y'': ''bar'', ''x'': ''foo''})


Otra forma de manejar con Python 2.x:

def foo(*args, **kwargs): if < kwarg-name > not in kwargs.keys(): kwargs[< kwarg-name >] = < kwarg-name-default-value > return bar(*args, **kwargs)

Esto maneja pasar *args arbitrarios a la llamada subyacente a diferencia de la respuesta de @neneneo.


Simplemente ponga los argumentos predeterminados antes de *args :

def foo(a, b=3, *args, **kwargs):

Ahora, b se establecerá explícitamente si lo pasa como un argumento de palabra clave o como el segundo argumento posicional.

Ejemplos:

foo(x) # a=x, b=3, args=(), kwargs={} foo(x, y) # a=x, b=y, args=(), kwargs={} foo(x, b=y) # a=x, b=y, args=(), kwargs={} foo(x, y, z, k) # a=x, b=y, args=(z, k), kwargs={} foo(x, c=y, d=k) # a=x, b=3, args=(), kwargs={''c'': y, ''d'': k} foo(x, c=y, b=z, d=k) # a=x, b=z, args=(), kwargs={''c'': y, ''d'': k}

Tenga en cuenta que, en particular, foo(x, y, b=z) no funciona porque b está asignado por posición en ese caso.

Este código también funciona en Python 3. Poner el arg predeterminado después de *args en Python 3 lo convierte en un argumento "solo palabras clave" que solo se puede especificar por nombre, no por posición. Si desea un argumento de palabra clave en Python 2, puede usar la solución de @ mgilson.


También puedes usar un decorador como este:

import functools def default_kwargs(**defaultKwargs): def actual_decorator(fn): @functools.wraps(fn) def g(*args, **kwargs): defaultKwargs.update(kwargs) return fn(*args, **defaultKwargs) return g return actual_decorator

Entonces solo hazlo:

@default_kwargs(defaultVar1 = defaultValue 1, ...) def foo(*args, **kwargs): # Anything in here

Por ejemplo:

@default_kwargs(a=1) def f(*args, **kwargs): print(kwargs[''a'']+ 1) f() # Returns 2 f(3) # Returns 4