2008-11-01 13 views
12

Me gustaría saber si es posible determinar si se pasó un parámetro de función con un valor predeterminado en Python. Por ejemplo, ¿cómo funciona dict.pop?Determinar si se pasó un parámetro con nombre

>>> {}.pop('test') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
KeyError: 'pop(): dictionary is empty' 
>>> {}.pop('test',None) 
>>> {}.pop('test',3) 
3 
>>> {}.pop('test',NotImplemented) 
NotImplemented 

¿Cómo determina el método pop que la primera vez que un valor de retorno por defecto no se aprobó? ¿Es esto algo que solo se puede hacer en C?

Gracias

Respuesta

7

Supongo que quiere decir "argumento de palabras clave" cuando dice "parámetro con nombre". dict.pop() no acepta el argumento de palabra clave, por lo que esta parte de la pregunta es discutible.

>>> {}.pop('test', d=None) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: pop() takes no keyword arguments 

Dicho esto, la manera de detectar si se proporcionó un argumento es el uso de la sintaxis *args o **kwargs. Por ejemplo:

def foo(first, *rest): 
    if len(rest) > 1: 
     raise TypeError("foo() expected at most 2 arguments, got %d" 
         % (len(rest) + 1)) 
    print 'first =', first 
    if rest: 
     print 'second =', rest[0] 

Con un poco de trabajo, y el uso de la sintaxis **kwargs también es posible emular completamente la convención de llamada pitón, donde los argumentos pueden ser proporcionados por posición o por su nombre, y los argumentos presentados múltiples veces (por posición y nombre) causa un error.

1

Puede hacerlo de esta manera:

def isdefarg(*args): 
    if len(args) > 0: 
     print len(args), "arguments" 
    else: 
     print "no arguments" 

isdefarg() 
isdefarg(None) 
isdefarg(5, 7) 

Ver la documentación de Python en calls para obtener información completa.

1
def f(one, two=2): 
    print "I wonder if", two, "has been passed or not..." 

f(1, 2) 

Si este es el significado exacto de su pregunta, creo que no hay manera de distinguir entre un 2 que se encontraba en el valor predeterminado y un 2 que se ha pasado. No encontré cómo lograr tal distinción incluso en el módulo inspect.

1

No estoy seguro si entiendo completamente qué es lo que quiere; sin embargo:

def fun(arg=Ellipsis): 
    if arg is Ellipsis: 
     print "No arg provided" 
    else: 
     print "arg provided:", repr(arg) 

hace que haga lo que usted quiere? Si no es así, entonces, como otros han sugerido, debe declarar su función con la sintaxis *args, **kwargs y verificar en el dict kwargs la existencia del parámetro.

11

La convención es a menudo utilizar arg=None y utilizar

def foo(arg=None): 
    if arg is None: 
     arg = "default value" 
     # other stuff 
    # ... 

para comprobar si fue aprobada o no. Permitir que el usuario pase None, lo que se interpretaría como si el argumento fuera no pasado.

+5

Esto no es útil si 'None' también es un valor significativo para el parámetro. El ejemplo es 'dict.pop' y su comportamiento cuando no se encuentra la clave: devuelve el segundo parámetro si está presente, o plantea KeyError en caso contrario. – Kos

+5

En ese caso, podría crear una variable de cierre con un objeto. 'MISSING = object(); def foo (arg = FALTA): si arg es FALTA: ... ' –

Cuestiones relacionadas