Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Initialisation par défaut d'une liste dans un constructeur

2 réponses
Avatar
ciol
Ceci est un appel au secours :

Voilà un petit bout de code et je comprends pas son comportement :
#--------------------------
class Truc:

def __init__(self, a_=[]):

print a_ #LE PROBLÈME EST ICI
self.a = a_


pt = Truc()

for x in [1, 2, 3]:
pt.a.append(x)


pt = Truc()
#--------------------------

Ce qui m'affiche :
[]
[1, 2, 3]

Alors que je voudrais que ça m'affiche :
[]
[]

!!!!!

2 réponses

Avatar
Laurent Pointal
Ceci est un appel au secours :

Voilà un petit bout de code et je comprends pas son comportement :
#--------------------------
class Truc:

def __init__(self, a_=[]):

print a_ #LE PROBLÈME EST ICI
self.a = a_


pt = Truc()

for x in [1, 2, 3]:
pt.a.append(x)


pt = Truc()
#--------------------------

Ce qui m'affiche :
[]
[1, 2, 3]

Alors que je voudrais que ça m'affiche :
[]
[]

!!!!!


C'est le problème des arguments par défaut.
Si un paramètre n'est pas donné, c'est la valeur par défaut qui est
utilisée, et comme en Python on travaille avec des références vers des
objets, on récupère toujours le même objet.
Si cet objet est mutable (typiquement liste ou dico), on modifie alors
l'objet valeur par défaut - d'où l'effet de bord que tu vois.

Solution:

class Truc:
def __init__(self, a_=None):
if a_ is None : a_ = []
print a_
self.a = a_



Cf
http://www.python.org/doc/current/tut/node6.html#SECTION006710000000000000000
"""Important warning: The default value is evaluated only once. This
makes a difference when the default is a mutable object such as a list,
dictionary, or instances of most classes. For example, the following
function accumulates the arguments passed to it on subsequent calls:"""

Avatar
ciol