estoy notando el siguiente:El valor por defecto en una función en Python
class c:
def __init__(self, data=[]):
self._data=data
a=c()
b=c()
a._data.append(1)
print b._data
[1]
Es este el comportamiento correcto?
estoy notando el siguiente:El valor por defecto en una función en Python
class c:
def __init__(self, data=[]):
self._data=data
a=c()
b=c()
a._data.append(1)
print b._data
[1]
Es este el comportamiento correcto?
Sí, es comportamiento correcto.
Sin embargo, a partir de su pregunta, parece que no es lo que esperaba.
Si usted quiere que coincide con sus expectativas, tenga en cuenta lo siguiente:
Regla 1. No utilice objetos mutables como valores por defecto.
def anyFunction(arg=[]):
No se creará un objeto de lista nuevo. El objeto de lista predeterminado para arg
se compartirá por todas partes.
Del mismo modo
def anyFunction(arg={}):
no creará un objeto dict fresco. Este dict predeterminado será compartido.
class MyClass(object):
def __init__(self, arg= None):
self.myList= [] if arg is None else arg
Esa es una forma común de proporcionar un valor de argumento predeterminado que es un objeto de lista nuevo y vacío.
'nunca work.' es un poco duro. 'No te dará un nuevo objeto mutable vacío en cada llamada', parece un poco más equilibrado. Si sabe que esto sucede, es posible que desee utilizar este comportamiento. – MattH
@MattH: Reutilizar el mismo objeto mutable a través de un valor predeterminado es tan extraño que resulta difícil encontrar un caso de uso sensato. Es un valor * predeterminado *, por lo que puede (o no) utilizarse como tal dependiendo del uso de la interfaz por parte del cliente. Sería tan difícil diagnosticar problemas con esto que estoy de acuerdo con mi formulación original. Especialmente para n00bz. –
Debe agregar un ejemplo de cómo solucionar esto. De lo contrario, la respuesta es buena y correcta. – ironfroggy
Esto es un escollo clásico. Ver http://zephyrfalcon.org/labs/python_pitfalls.html, sección 5: "mutables argumentos por omisión"
Siempre hacen funciones como esta a continuación:
def __init__ (self, data = None):
if data is None:
data = []
self._data = data
Como alternativa también se puede utilizar data = data or []
, pero que impide que el usuario pase a vacías parámetros (''
, 0
, False
etc.).
Por supuesto, también puede hacer 'if not data: data = []'. – voyager
su ejemplo 'data = data or []' funciona bien para las listas vacías que se pasan. Usted diría que 'data' será' [] o [] 'para que vea el primero y vea que se evalúa como" falso ", luego tomará el otro valor. – tgray
Lo sé, mi punto fue que cuando pasa 'False' por ejemplo,' [] 'se usará como el valor, aunque pasó' False'. – poke
Lea la documentación de marcado para ver cómo formatear correctamente el código. Está en el lado derecho de la página. Por favor actualice su pregunta para sangrar el código de 4 espacios. –
relacionadas: http://stackoverflow.com/questions/1011431/python-things-one-must-avoid, http://stackoverflow.com/questions/1534407/python-object-intialization-bug-or-am-i -misunderstanding-cómo-objetos-trabajo, http://stackoverflow.com/questions/1651154/why-are-default-arguments-evaluated-at-definition-time-in-python –