Python, argumentos de palabras clave predeterminados después de argumentos posicionales de longitud variable


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

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 poder 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.

Author: Donald Duck, 2011-05-09

2 answers

Funciona, pero solo en Python 3. Véase PEP 3102. Al echar un vistazo a los documentos de" novedades", parece que no hay 2.x backport, así que no tienes suerte. Tendrás que aceptar cualquier argumento de palabra clave (**kwargs) y analizarlo manualmente. Puedes usar d.get(k, default) para obtener d[k] o default si eso no está ahí. Para eliminar un argumento de kwargs, por ejemplo, antes de llamar a un método de superclase, use d.pop.


Tenga en cuenta que en def get(self, *args, raw=False, vars=None):, el raw=False y vars=None no tienen nada que ver con argumentos de palabras clave. Esos son los valores predeterminados de los argumentos. Los argumentos con un valor predeterminado se pueden pasar posicionalmente, y los argumentos sin un valor predeterminado 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 solo palabras clave no son necesarios para tener un valor predeterminado. Venir después del argumento *args es lo que los marca como solo palabras clave, no la presencia de un valor predeterminado:

def f(*args, a): pass
# a is a mandatory, keyword-only argument
 63
Author: funky-future,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-18 20:29:12

La sintaxis de Python no permite args variables en argumentos de función y palabra clave con valor predeterminado al mismo tiempo. Si debe tener argumentos de palabra clave junto con el número arbitrario de argumentos posicionales, también debe permitir el número arbitrario de argumentos de palabra clave.

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

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

Si no utiliza los argumentos de palabras clave adicionales en absoluto, tiene nada de qué preocuparse. Esto hace que la función sea un poco menos auto-documentada, lo que puede hacer con un docstring correctamente escrito.

 42
Author: Imran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-09 17:14:38