69

Pensé que podría usar parámetros nombrados después de parámetros posicionales de longitud variable en una llamada de función en Python 2, pero obtengo un SyntaxError cuando importo una clase python. Estoy escribiendo con el siguiente método "get", por ejemplo:Python, argumentos predeterminados de palabras clave después de argumentos posicionales de longitud variable

class Foo(object): 
    def __init__(self): 
     print "You have created a Foo." 

    def get(self, *args, raw=False, vars=None): 
     print len(args) 
     print raw 
     print vars 

El error parece:

def get(self, *args, raw=False, vars=None): 
        ^
SyntaxError: invalid syntax 

Me gustaría ser capaz de llamar al método de varias maneras:

f = Foo() 
f.get(arg1, arg2) 
f.get(arg1, raw=True) 
f.get(arg1, arg2, raw=True, vars=something) 

etc.

Respuesta

61

sí funciona, pero sólo en Python 3. Véase PEP 3102. Al echar un vistazo a los documentos "qué hay de nuevo", parece que no hay soporte 2.x, por lo que no tiene suerte. Tendrá que aceptar cualquier argumento de palabra clave (**kwargs) y analizarlo manualmente. Puede usar d.get(k, default) para obtener d[k] o default si eso no está allí. Para eliminar un argumento de kwargs, p. antes de llamar a un método de superclase, use d.pop.


Nótese que en def get(self, *args, raw=False, vars=None):, la raw=False y vars=None no tienen nada que ver con los argumentos de palabras clave. Esos son valores de argumento predeterminados. Argumentos con un valor por defecto se pueden pasar posicionalmente, y argumentos sin un valor por defecto se pueden pasar por palabra clave:

def f(a=1): pass 
f(2) # works, passing a positionally 
def f(a): pass 
f(a=2) # works, passing a by keyword 

Del mismo modo, los argumentos de palabras clave sólo no están obligados a tener un valor por defecto. Viniendo después del argumento *args es lo que los marca como palabra clave única, no la presencia de un valor por defecto: la sintaxis

def f(*args, a): pass 
# a is a mandatory, keyword-only argument 
+0

¡Gracias a ti y a Imran! Su respuesta con el bloque de código de Imran y la sugerencia de docstring respondieron la pregunta perfectamente. – jkmacc

41

de Python no permite args variables en la función y los argumentos de palabras clave con el valor por defecto al mismo tiempo. Si debe tener argumentos de palabras clave junto con una cantidad arbitraria de argumentos posicionales, también debe permitir el uso de una cantidad arbitraria de argumentos de palabra clave.

Este es un patrón común para proporcionar valores por defecto de los argumentos de palabras clave, así como permitir que cualquier número de argumentos posicionales:

def foo(*args, **kwargs): 
    raw = kwargs.pop('raw', False) 
    vars = kwargs.pop('vars', None) 

Si usted no utiliza los argumentos de palabras clave adicionales para nada, no tienes nada preocuparse de. Esto hace que la función sea un poco menos auto-documentada, lo que puede compensar con una docstring escrita correctamente.

Cuestiones relacionadas