Considérons trois fonctions:
def my_func1():
print "Hello World"
return None
def my_func2():
print "Hello World"
return
def my_func3():
print "Hello World"
Ils semblent tous retourner Aucun. Existe-t-il des différences entre la façon dont la valeur renvoyée de ces fonctions se comporte? Y a-t-il des raisons de préférer l'une ou l'autre?
Sur le comportement actuel, il n'y a pas de différence. Ils retournent tous None
et c'est tout. Cependant, il y a un temps et un lieu pour tout cela. Les instructions suivantes décrivent en gros comment utiliser les différentes méthodes (ou au moins comment on m'a appris à les utiliser), mais ce ne sont pas des règles absolues. Vous pouvez donc les mélanger si vous en ressentez le besoin.
return None
Cela indique que la fonction est en effet destinée à renvoyer une valeur pour une utilisation ultérieure, et dans ce cas, elle retourne None
. Cette valeur None
peut alors être utilisée ailleurs. return None
n'est jamais utilisé s'il n'y a pas d'autres valeurs de retour possibles de la fonction.
Dans l'exemple suivant, nous retournons person
'mother
si la person
donnée est un humain. Si ce n'est pas un humain, nous retournons None
puisque le person
n'a pas de mother
(supposons que ce ne soit pas un animal ou à peu près).
def get_mother(person):
if is_human(person):
return person.mother
else:
return None
return
Ceci est utilisé pour la même raison que break
dans les boucles. La valeur de retour n'a pas d'importance et vous voulez seulement quitter la fonction entière. C'est extrêmement utile à certains endroits, même si vous n'en avez pas souvent besoin.
Nous avons 15 prisoners
et nous savons que l'un d'entre eux a un couteau. Nous parcourons chaque prisoner
un par un pour vérifier s’ils ont un couteau. Si nous frappons la personne avec un couteau, nous pouvons simplement quitter la fonction parce que nous savons qu’il n’ya qu’un seul couteau et qu’aucune raison ne permet de vérifier le reste de la prisoners
. Si nous ne trouvons pas la prisoner
avec un couteau, nous lançons une alerte. Cela pourrait être fait de différentes manières et utiliser return
n'est probablement même pas la meilleure solution, mais c'est simplement un exemple pour montrer comment utiliser return
pour quitter une fonction.
def find_prisoner_with_knife(prisoners):
for prisoner in prisoners:
if "knife" in prisoner.items:
prisoner.move_to_inquisition()
return # no need to check rest of the prisoners nor raise an alert
raise_alert()
Remarque: vous ne devriez jamais faire var = find_prisoner_with_knife()
, car la valeur de retour n'est pas destinée à être interceptée.
return
du toutCeci retournera également None
, mais cette valeur n'est pas destinée à être utilisée ou capturée. Cela signifie simplement que la fonction s'est terminée avec succès. C'est fondamentalement la même chose que return
dans void
fonctions dans des langages tels que C++ ou Java.
Dans l'exemple suivant, nous définissons le nom de la mère de la personne, puis la fonction se ferme une fois l'opération terminée.
def set_mother(person, mother):
if is_human(person):
person.mother = mother
Remarque: vous ne devriez jamais faire var = set_mother(my_person, my_mother)
, car la valeur de retour n'est pas destinée à être interceptée.
Oui, ils sont tous pareils.
Nous pouvons examiner le code machine interprété pour confirmer qu’ils font tous exactement la même chose.
import dis
def f1():
print "Hello World"
return None
def f2():
print "Hello World"
return
def f3():
print "Hello World"
dis.dis(f1)
4 0 LOAD_CONST 1 ('Hello World')
3 PRINT_ITEM
4 PRINT_NEWLINE
5 5 LOAD_CONST 0 (None)
8 RETURN_VALUE
dis.dis(f2)
9 0 LOAD_CONST 1 ('Hello World')
3 PRINT_ITEM
4 PRINT_NEWLINE
10 5 LOAD_CONST 0 (None)
8 RETURN_VALUE
dis.dis(f3)
14 0 LOAD_CONST 1 ('Hello World')
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
Ils renvoient chacun le même singleton None
- Il n'y a pas de différence fonctionnelle.
Je pense qu'il est raisonnablement idiomatique de laisser la déclaration return
sauf si vous en avez besoin pour quitter la fonction plus tôt (dans ce cas, un return
dépourvu est plus courant), ou renvoyer autre chose que None
. Il est également logique et apparemment idiomatique d’écrire return None
lorsqu’il s’agit d’une fonction ayant un autre chemin qui renvoie autre chose que None
. Écrire explicitement return None
indique clairement au lecteur qu'il existe une autre branche qui renvoie quelque chose de plus intéressant (et que le code d'appel devra probablement gérer les deux types de valeurs de retour).
Souvent en Python, les fonctions qui retournent None
sont utilisées comme void
fonctions en C - Leur but est généralement d'opérer sur les arguments d'entrée à la place (sauf si vous utilisez données globales (frissons)). Retourner None
rend généralement plus explicite le fait que les arguments ont été mutés. Cela explique un peu plus pourquoi il est logique de laisser de côté la déclaration return
du point de vue des "conventions de langage".
Cela dit, si vous travaillez dans une base de code qui a déjà des conventions prédéfinies autour de ces choses, je ferais de même pour aider la base de code à rester uniforme ...
En termes de fonctionnalités, elles sont toutes identiques, la différence entre elles réside dans la lisibilité du code et son style (ce qui est important à prendre en compte).