web-dev-qa-db-fra.com

retour, retour Aucun, et aucun retour?

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?

326
Clay Wardell

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.

Utiliser 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

Utiliser 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.

Ne pas utiliser return du tout

Ceci 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.

430
user2032433

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      
28
David Marx

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 ...

18
mgilson

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).

2
Yehuda Schwartz