J'écrivais du code en Python et je me suis dit "Est-ce vraiment?"
def wrap_list(value, base_list = []):
base_list.append(value)
return base_list
Supposons que vous ayez un code comme celui-ci. Si vous appelez cela plusieurs fois, en omettant le deuxième argument:
print(wrap_list(1)) # => [1]
print(wrap_list(2)) # => [1, 2]
Le résultat est. Je veux que ce soit «[2]» la deuxième fois.
Vous pouvez voir ce qui se passe en affichant l'ID de l'objet avec la fonction ʻid`.
def wrap_list(value, base_list = []):
print(id(base_list)) # debug print
base_list.append(value)
return base_list
wrap_list(1) # => 4373211008
wrap_list(2) # => 4373211008
L'ID d'objet de base_list
est le même dans les deux appels. En d'autres termes, une liste vide n'est pas générée pour chaque appel, mais une seule fois.
Au fait, je l'ai aussi essayé sur Ruby:
def wrap_list(value, base_list = [])
puts base_list.object_id
base_list << value
end
wrap_list(1) # => 70218064569220
wrap_list(2) # => 70218064588580
Cela semble être généré pour chaque appel.
Je ne pense pas que j'écrirais du code comme celui ci-dessus en Python:
class WrappedList(object):
def __init__(self, initial = []):
self.list = initial
def append(self, value):
self.list.append(value)
Bien sûr, la même chose se produit dans de tels cas, vous devez donc faire attention.
Le problème fondamental est qu'il n'est pas initialisé pour chaque appel et que la solution de contournement est simplement "n'effectuez pas d'opérations destructives". Si vous avez besoin d'une opération destructive, vous pouvez définir l'argument par défaut lui-même sur «Aucun», et s'il est «Aucun», initialisez-le avec une liste vide.
Recommended Posts