IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Argument par défaut : bug ou spécification?


Sujet :

Python

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 51
    Par défaut Argument par défaut : bug ou spécification?
    Bonjour,

    Je viens de me tirer les cheveux 1 bonne heure sur un code qui avait un comportement bizarre ... les éléments d'un tableaux semblaient faire tous référence au même objet, ce qui n'était pas le cas. En réalité, c'était l'un des composant d'un de ces objets qui référait au même .... j'ai alors cherché un peu, et ca vient de mon constructeur de mon objet.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class MyClass :
        def __init__(self,d={}) :
             self.d = d
    a=MyClass()
    b=MyClass()
    print a.d,b.d
    >>> {},{}  #jusque là tout va bien
    #mais :
    a.d["test"] = 1
    print a.d,b.d
    >>> {"test":1},{"test":1} # (!)
    Apparement, l'argument par défaut est créé une fois pour toute et tous les appels renvoient tous aux même.
    Cette optimisation est compréhensible dans une méthode bébête, mais dans un constructeur, je trouve ce comportement très surprenant.

    Alors bug ou spécification du langage (j'avoue que j'ai pas eu le courage d'aller fouiller dans la spéc)?

  2. #2
    Expert confirmé
    Avatar de Guigui_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2002
    Messages : 1 864
    Par défaut
    l'affectation ne copie pas l'objet mais son pointeur => tous tes self.d pointe sur le même endroit
    =>

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 51
    Par défaut
    Merci de l'astuce du .copy(), je connaissais pas!

    Mais je matiens, je trouve ce comportement surprenant !

  4. #4
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    C'est dû au fait que les arguments par défaut ne sont créé une seule fois lors de la création de la classe. Cela pose des problèmes lorsqu'un argument par défaut est un objet mutable (comme un dictionnaire ou un liste). Dans ce cas, la solution recommandé ici est:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class MyClass :
        def __init__(self, d=None) :
             if d is None:
                 d = {}
             self.d = d
    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  5. #5
    Membre émérite
    Avatar de GnuVince
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2004
    Messages
    679
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2004
    Messages : 679
    Par défaut
    Utilise la méthode montrée par Thierry, c'est la façon "Pythonique" de faire.

Discussions similaires

  1. fonction sans arguments par défaut
    Par Doksuri dans le forum Langage
    Réponses: 1
    Dernier message: 15/09/2010, 17h44
  2. template, itérateurs et argument par défaut de fonction
    Par goran kajfes dans le forum Langage
    Réponses: 5
    Dernier message: 24/05/2009, 18h00
  3. Réponses: 3
    Dernier message: 28/11/2008, 14h02
  4. Chaine littérale en tant qu'argument par défaut
    Par Daemonovae dans le forum C++
    Réponses: 3
    Dernier message: 24/11/2006, 20h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo