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 :

valeur par défaut dans un argument


Sujet :

Python

  1. #1
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Par défaut valeur par défaut dans un argument
    Bonjour,

    J'ai besoin d'une confirmation sur un comportement d'une fonction et ses paramètres par défaut. Comme je ne sais pas comment appeler ce comportement, je ne sais pas trop où chercher sur la toile une explication.

    Bref voilà une fonction fabrique:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def factory():
        _name = "kango"
        def hello(name=_name):    
            print "hello",name
        return hello
    Et voici un exemple d'utilisation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    >>> myfunc=factory()
    >>> myfunc()
    hello cedric
    >>> _name     
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    NameError: name '_name' is not defined
    J'interprète ceci de la façon suivante:

    l'écriture

    est interprété exactement comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    def hello(name="kango"):
    Comme s'il y avait une "résolution" (mot peut être mal choisi) non pas à l'exécution de la fonction mais lors de la déclaration de celle ci.

    Ca tombe bien, ce comportement m'arrange énormément mais j'aimerais le comprendre mieux avant de m'en servir. J'ai isolé le comportement sur un cas simple mais je me pose la question car je suis en train d'écrire une métaclasse (ma première ).

    Que pouvez vous me dire sur ce comportement ?

    Merci d'avance pour vos réponses

  2. #2
    Membre émérite
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Par défaut
    tu as bien déduit, mais en plus de cela, _name est défini à l'intérieur de factory() ce qui fait qu'on de peut normalement pas accéder a cette variable.

    Tu peux observer le comportement suivant qui confirme ce que tu as avancé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    >>> def ab(a=[]):
    	a+=[len(a)]
    	return a[:]
     
    >>> ab()
    [0]
    >>> ab()
    [0, 1]
    >>> ab()
    [0, 1, 2]
    >>> ab()
    [0, 1, 2, 3]
    Donc, les valeur par défauts des arguments optionels ne sont définis qu'une fois, et gardés en mémoire jusqu'a ce que (je suppose) la fonction soit supprimée.

  3. #3
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Par défaut
    ok je vois, par chance je ne suis jamais sur le cas de figure que tu montres (avec une valeur par défaut de type muable) sinon... ben sinon je serais venu ici poser la question

    ça me rassure ce que tu me dis N.tox, merci pour ta réponse

    c'est un mécanisme propre à python ? ou plutôt commun dans les autres langages (qui permettent d'avoir des arguments avec valeur par défaut) ?

  4. #4
    Membre émérite
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Par défaut
    Aucune idée, mais étant donnée que c'est une économie de ressource cpu, ça m'étonnerait que ce soit le seul.

  5. #5
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Testons testons...

    C++
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #include <stdio.h>
     
    class Default {
    public:
            Default() {
     
            }
    };
     
     
    void function(Default* def=new Default()) {
            printf("%p\n", def);
    }
     
    int main() {
            function();
            function();
     
            return 0;
    }
    Exécution:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ~/smallprog/default $ ./default 
    0x9a3c008
    0x9a3c018
    On a donc bien deux objets différents en C++


    PHP:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <?php
     
    class DefaultCls {
            private static $count = 0;
     
            function __construct() {
                    ++self::$count;
            }
     
            static function getCount() {
                    return self::$count;
            }
    }
     
    function func(DefaultCls $arg=new DefaultCls()) {
     
    }
     
    func();
    func();
    print(DefaultCls::getCount());
     
    ?>
    Eh bien ça ne fonctionne tout simplement pas: PHP refuse le new dans les arguments par défaut.

    Dans le java, il n'y a pas d'argument par défaut.
    Idem pour le C.
    En Perl, c'est encore une autre affaire ^^

    J'ai pas le courage de tester pour le javascript


    De manière générale, c'est plutôt une aberration et quelque chose d'inattendu de n'avoir qu'une seule instance pour les arguments par défaut. D'ailleurs on se sert de variables statiques pour ce genre de choses.
    Je pense donc que python doit être un des seuls langages à faire ça.

  6. #6
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Par défaut
    Merci pour les tests Antoine_935

    De manière générale, c'est plutôt une aberration et quelque chose d'inattendu de n'avoir qu'une seule instance pour les arguments par défaut. D'ailleurs on se sert de variables statiques pour ce genre de choses.
    "aberration", je ne sais pas; comme je le disais ce comportement m'arrange également dans un cas bien précis (métaclasse) où les variables statiques ne peuvent pas m'aider. Je fais peut être une mauvaise utilisation de la métaclasse...

    Je serais surpris que Python fasse de quelque chose d'aussi "inattendu" pour une mauvaise raison. A moins que ce soit une contrainte de la philosophie Python

    Je vais isoler un cas pour illustrer mon propos mais je pense que j'ouvrirais un nouveau topic.

    Encore merci pour vos réponses

  7. #7
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Citation Envoyé par kango Voir le message
    A moins que ce soit une contrainte de la philosophie Python
    Je ne pense pas vraiment que ce soit un choix de philosophie, mais plutot de facilité.
    En fait, la manière dont Python stocke les arguments par défaut ne permettrait tout simplement pas de faire une instanciation pour chaque exécution.
    En effet, dans le tuple des arguments par défaut, ils stockent des object, et non un petit bout de code.
    Or, pour instancier, il faut un bout de code.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> def test(a=[]):
    ...     pass
    ... 
    >>> test.func_defaults
    ([],)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Valeur par défaut dans un ALTER TABLE
    Par HULK dans le forum Langage SQL
    Réponses: 11
    Dernier message: 27/12/2005, 10h04
  2. Valeur par défaut dans un DbLookupCombobox
    Par defluc dans le forum Bases de données
    Réponses: 2
    Dernier message: 22/09/2005, 14h04
  3. [Débutant(e)]valeur par défaut dans méthodes
    Par seiryujay dans le forum Langage
    Réponses: 3
    Dernier message: 13/07/2005, 12h02
  4. Sélection valeur par défaut dans une zone de liste
    Par Cécile154 dans le forum IHM
    Réponses: 2
    Dernier message: 15/02/2005, 18h20
  5. Valeur par défaut dans une table objet
    Par Ricky81 dans le forum Oracle
    Réponses: 12
    Dernier message: 18/03/2004, 11h52

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