2011-06-22 14 views
28

Duplicar posibles:
“Least Astonishment” in Python: The Mutable Default Argumentparámetros opcionales en las funciones de Python y sus valores predeterminados

Estoy un poco confundido acerca de cómo los parámetros opcionales trabajar en Python funciones/métodos.

Tengo el siguiente bloque de código:

>>> def F(a, b=[]): 
...  b.append(a) 
...  return b 
... 
>>> F(0) 
[0] 
>>> F(1) 
[0, 1] 
>>> 

Por qué F(1) vuelve [0, 1] y no [1]?

Quiero decir, ¿Qué está pasando dentro de?

+0

se puede ver que fácilmente con sólo imprimir el valor de b antes de añadir a la lista. :) – sam

Respuesta

38

Good doc de PyCon hace un par de años - Default parameter values explained. Pero básicamente, dado que las listas son objetos mutables, y los argumentos de las palabras clave se evalúan en el momento de la definición de la función, cada vez que llamas a la función, obtienes el mismo valor predeterminado.

La forma correcta de hacer esto sería:

def F(a, b=None): 
    if b is None: 
     b = [] 
    b.append(a) 
    return b 
8

Default parameters son, bastante intuitiva, algo así como variables miembro del objeto de función.

Los valores de los parámetros predeterminados se evalúan cuando se ejecuta la definición de la función. Esto significa que la expresión se evalúa una vez, cuando se define la función, y se utiliza el mismo valor "precalculado" para cada llamada. Esto es especialmente importante para comprender cuándo un parámetro predeterminado es un objeto mutable, como una lista o un diccionario: si la función modifica el objeto (por ejemplo, al agregar un elemento a una lista), el valor predeterminado se modifica en efecto.

http://docs.python.org/reference/compound_stmts.html#function

listas son unos objetos mutables; puedes cambiar sus contenidos La forma correcta para obtener una lista predeterminada (o diccionario, o conjunto) es crearlo en tiempo de ejecución en su lugar, dentro de la función:

def good_append(new_item, a_list=None): 
    if a_list is None: 
     a_list = [] 
    a_list.append(new_item) 
    return a_list 
Cuestiones relacionadas