procedimientos - función python*args y** kwargs con otros argumentos de palabra clave especificados
lista de funciones de python (3)
Tengo una clase de Python con un método que debería aceptar argumentos y argumentos de palabras clave de esta manera
class plot:
def __init__(self, x, y):
self.x = x
self.y = y
def set_axis(self, *args, xlabel="x", ylabel="y", **kwargs):
for arg in args:
<do something>
for key in kwargs:
<do somethng else>
al llamar:
plt = plot(x, y)
plt.set_axis("test1", "test2", xlabel="new_x", my_kwarg="test3")
Me TypeError: set_axis() got multiple values for keyword argument ''xlabel''
el error: TypeError: set_axis() got multiple values for keyword argument ''xlabel''
De todos modos si configuro mi método como
class plot:
def __init__(self, x, y):
self.x = x
self.y = y
def set_axis(self, xlabel="x", ylabel="y", *args, **kwargs):
for arg in args:
<do something>
for key in kwargs:
<do somethng else>
y llama:
plt = plot(x, y)
plt.set_axis(xlabel="new_x", "test1", "test2", my_kwarg="test3")
Obtengo SyntaxError: non-keyword arg after keyword arg
, como estaba esperando. ¿Qué pasa con el primer caso? ¿Cómo debo decirle a mi método que acepte cualquier argumento de usuario y argumento de palabras clave, que no sean los predeterminados? (Espero que mi pregunta sea lo suficientemente clara)
En Python 3 esto funciona:
Python 3.2.3 (default, Oct 19 2012, 19:53:16)
>>> def set_axis(self, *args, xlabel="x", ylabel="y", **kwargs):
... print(args, xlabel, ylabel, kwargs)
...
>>> set_axis(None, "test1", "test2", xlabel="new_x", my_kwarg="test3")
(''test1'', ''test2'') new_x y {''my_kwarg'': ''test3''}
>>>
Utilizarías un patrón diferente:
def set_axis(self, *args, **kwargs):
xlabel = kwargs.get(''xlabel'', ''x'')
ylabel = kwargs.get(''ylabel'', ''y'')
Esto le permite usar * y ** mientras mantiene los valores de retorno si los argumentos de palabra clave no están definidos.
Aquí hay una ligera tweek a la respuesta de Jure C.
def set_axis(self, *args, **kwargs):
xlabel = kwargs.pop(''xlabel'', ''x'')
ylabel = kwargs.pop(''ylabel'', ''y'')
Cambié a pop
para eliminar xlabel
y ylabel
de kwargs
si está presente. Hice esto porque el resto del código en la pregunta original contiene un ciclo que se supone que itera a través de todos los kwargs
excepto para xlabel
y ylabel
.