Necesita comprender cómo funcionan los valores predeterminados para usarlos de manera efectiva.
Las funciones son objetos. Como tal, tienen atributos. Entonces, si creo esta función:
>>> def f(x, y=[]):
y.append(x)
return y
He creado un objeto. Aquí están sus atributos:
>>> dir(f)
['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__',
'__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__',
'__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals',
'func_name']
Uno de ellos es func_defaults
. Eso suena prometedor, ¿qué hay ahí?
>>> f.func_defaults
([],)
Esa es una tupla que contiene los valores predeterminados de la función. Si un valor predeterminado es un objeto, la tupla contiene una instancia de ese objeto.
Esto conduce a un comportamiento bastante contrario a la intuición si usted está pensando que f
añade un elemento a una lista, devolviendo una lista que contiene sólo ese elemento si no se proporciona la lista:
>>> f(1)
[1]
>>> f(2)
[1, 2]
Pero si sabe que el valor por defecto es una instancia de objeto que se almacena en uno de los atributos de la función, que es mucho menos contrario a la intuición:
>>> x = f(3)
>>> y = f(4)
>>> x == y
True
>>> x
[1, 2, 3, 4]
>>> x.append(5)
>>> f(6)
[1, 2, 3, 4, 5, 6]
Sabiendo esto, está claro que si se desea un valor por defecto del parámetro de una función que sea una lista nueva (o cualquier ob nuevo objeto), no se puede ocultar una instancia del objeto en func_defaults
. Debe crear uno nuevo cada vez que se llame a la función:
>>>def g(x, y=None):
if y==None:
y = []
y.append(x)
return y
¡Debe aceptar una respuesta si se solucionó el problema! Varias de las respuestas parecen muy informativas. Aunque la pregunta es antigua, creo que sería una buena idea dar una respuesta a su sello de aprobación – eipxen
posible duplicado de ["Menos asombro" en Python: el argumento predeterminado mutable] (http://stackoverflow.com/ questions/1132941/least-atightishment-in-python-the-mutable-default-argument) –