-1
votes

Liste d'arguments par défaut Python - Comportement incohérent

J'ai une situation dans laquelle la valeur de l'argument par défaut dans une tête de fonction est affectée par une clause if-clause dans l'organisme de fonction. J'utilise Python 3.7.3.

Définitions de fonction

Nous avons deux fonctions f et j . Je comprends le comportement des deux premières fonctions. Je ne comprends pas le comportement de la deuxième fonction. xxx

comportement de fonction que je comprends

Nous appelons la première fonction trois fois: xxx

la liste vide [] est initialisé sur le premier appel de la fonction. Lorsque nous appendons 5 à l alors l'instance de la liste dans la mémoire est modifiée. Par conséquent, sur la deuxième fonction, cette liste modifiée est attribuée à l . Semble raisonnable.

Comportement de la fonction que je n'ai pas untertand

maintenant, nous appelons la troisième fonction ( j ) et obtenez: xxx

Selon la sortie, l est une liste vide au début de chaque appel de la fonction j . Lorsque je supprimai la clause if-clause, dans le corps de la fonction j la fonction est égale à la fonction f et donne la même sortie. Par conséquent, la clause IF-CLAUSE semble avoir un effet secondaire. Test de len (l) == 0 au lieu de l == [] dans j a le même effet.

liée à

ma question est liée à:


14 commentaires

Ce serait plus facile à suivre si vous publiez une fonction dont vous ne comprenez pas le problème, expliquez votre problème avec cela et laissez toutes les autres fonctions.


Il n'est pas clair pour moi pourquoi c'était inattendu / contraire. Vous attendiez-vous l = [] à l'intérieur de la fonction pour modifier la valeur par défaut liée?


@khelwood j'ai enlevé la quatrième fonction.


@jonrsharpe Je m'attendrais à ce que la fonction j a la même valeur de retour que la fonction f . Cependant, ce n'est pas le cas. Les instructions d'impression dans l'organisme de fonction sont pour débogage .


Mais pourquoi vous attendiez-vous à cela? Quelle a été votre hypothèse pour la manière dont cela fonctionnerait qui vous a amené à attendre le même comportement?


@ Daniel.neumann Je voulais dire laisser tomber toutes les autres fonctions , à l'exception de celle que vous demandez. Et expliquez clairement pourquoi le comportement vous confond.


@khelwood a mis à jour en conséquence.


@jonrsharpe Le l devient initialisé différemment en fonction de la clause si dans le corps de la fonction. Veuillez comparer les lignes f, intérieures et j, avant si après le deuxième appel de f et j . Dans f Le l est une liste avec la valeur 5 . Dans j le l est une liste vide. Cependant, il devrait s'agir d'une liste [5] .


pourquoi devrait-il être? Encore une fois, "Vous attendiez-vous l = [] à l'intérieur de la fonction pour modifier la valeur par défaut liée?" (ou l = [5] le même) au moment où vous semblez demander à "Quelle est la différence entre ajouter plusieurs articles à une seule liste et ajouter un seul élément à plusieurs listes" et la réponse semble évidente, alors je suis Essayer de comprendre où votre compréhension quitte ce qui se passe.


@jonrsharpe Partie 1: Une liste vide [] est initialisée sur le premier appel de la fonction f . La valeur par défaut pour l est: pointez sur cette liste vide. Dans le corps de f , nous appouverons une valeur à la liste et renvoyez-la. Sur le deuxième appel de f , la liste vide [] n'est pas nouvellement initialisée mais l pointe vers l'emplacement dans la mémoire où la liste vide était initialement initialisé. Depuis le premier appel de F cette liste n'est plus vide. Par conséquent, l n'a pas la valeur d'une liste vide mais une liste avec une seule valeur. Si nous appelons f dix fois, nous nous retrouverons avec une liste de dix éléments.


@ daniel.neumann no, par La question vous ' VE lié à La liste vide est initialisée lorsque la fonction est créée , pas quand il est appelé.


@jonrsharpe Partie 2: Nous examinons maintenant j . Je m'attendais à j pour fonctionner de la même manière. Au moins l'instruction d'impression avant le si -clause devrait générer [5] dans le deuxième appel de j .


@jonrsharpe Alors que je tape ces commentaires, la question a été répondue par GlibDudd. La liste (vers laquelle l pointe) modifiée dans j n'est pas la liste définie comme valeur par défaut.


On a l'impression que vous pourriez avoir répondu à "oui" soit dans la fois que j'ai demandé et sauvé un peu de dactylographie. La même réponse a été fournie il y a quelque temps par Jean-François aussi


3 Réponses :


1
votes

Si tout résume à ceci:

if L == [5]:
    L[:] = []


2 commentaires

Mon irritation est liée à la fonction j où nous testons si l == [] .


c'est la même chose. Le problème est que l nom est réaffecté (même chose répétée dans la réponse acceptée BTW)



1
votes

Modifiez vos instructions d'impression pour imprimer également ID (L) CODE>:

>>> j()
j, before if: [] 2844163925576
j, after if:  [] 2844163967688
[5]


0 commentaires

1
votes
assigning default value
inside b [10]
[10]
inside b [10, 10]
[10, 10]
inside b [10, 10, 10]
[10, 10, 10]

1 commentaires

Python 2.7 d'occasion afin de vérifier la syntaxe de vérification de l'impression si vous exécutez dans Python 3 ou plus