• [^] # Re: On s'en bat le steak

    Posté par . En réponse au journal Typage statique pour Python. Évalué à 3.

    Je suis entrain de me former à Python. Comment expliquer ce comportement, et comment faudrait-il modifier le code pour avoir un bon fonctionnement ?

    Le comportement observé est du au fait que les arguments optionnels ne sont évalués qu'une seule fois lors de la définition de la fonction. S'ils sont mutables, et qu'on les affecte comme attribut aux objets de la classe, ils ne sont alors pas propre aux objets mais deviennent des variables de classe. Pour éviter cela, si ce n'est pas ce que l'on souhaite, il faut utiliser la solution de flan et utiliser la valeur None comme paramètre par défaut, puis tester dessus pour avoir des listes vides différentes pour chaque objet de la classe.

    >>> class Test:
    ... def __init__(self, items=None):
    ... self.items = [] if items is None else items
    ... 
    ... def add(self, item):
    ... self.items.append(item)
    ... 
    >>> a = Test()
    >>> a.add('foo')
    >>> b = Test()
    >>> b.add('bar')
    >>> a.items
    ['foo']
    >>> b.items
    ['bar']

    En OCaml, par exemple, les arguments optionnels sont implicitement représentés par le type polymorphe 'a option :

    let foo ?x () =
     match x with
     | None -> print_endline "pas d'argument optionnel"
     | Some i -> Printf.printf "l'entier %i\n" i
    ;;
    val foo : ?x:int -> unit -> unit = <fun>
    foo ~x:2 ();;
    l'entier 2
    - : unit = ()
    foo ();;
    pas d'argument optionnel
    - : unit = ()

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.