retour, retour Geen en helemaal geen retour?

Overweeg drie functies:

def my_func1():
  print "Hello World"
  return None
def my_func2():
  print "Hello World"
  return
def my_func3():
  print "Hello World"

Ze lijken allemaal Geen te retourneren. Zijn er verschillen tussen hoe de geretourneerde waarde van deze functies zich gedraagt? Zijn er redenen om de ene boven de andere te verkiezen?


Antwoord 1, autoriteit 100%

Op het feitelijke gedrag is er geen verschil. Ze retourneren allemaal Noneen dat is alles. Voor al deze zaken is echter een tijd en plaats.
De volgende instructies zijn in feite hoe de verschillende methoden moeten worden gebruikt (of in ieder geval hoe mij is geleerd dat ze moeten worden gebruikt), maar het zijn geen absolute regels, dus je kunt ze door elkaar halen als je dat nodig acht.

Gebruik return None

Dit geeft aan dat de functie inderdaad bedoeld is om een waarde terug te geven voor later gebruik, en in dit geval wordt Nonegeretourneerd. Deze waarde Nonekan dan elders worden gebruikt. return Nonewordt nooit gebruikt als er geen andere mogelijke return-waarden van de functie zijn.

In het volgende voorbeeld geven we de personvan motherals de gegeven mothereen mens is. Als het geen mens is, retourneren we Noneaangezien de mothergeen personheeft (laten we aannemen dat het geen dier is of zo).

def get_mother(person):
    if is_human(person):
        return person.mother
    else:
        return None

Gebruik return

Dit wordt om dezelfde reden gebruikt als breakin loops. De retourwaarde doet er niet toe en u wilt alleen de hele functie verlaten. Het is op sommige plaatsen buitengewoon nuttig, ook al heb je het niet vaak nodig.

We hebben 15 prisonersen we weten dat een van hen een mes heeft. We lussen via elk prisoneréén voor één om te controleren of ze een mes hebben. Als we de persoon met een mes raken, kunnen we gewoon de functie verlaten omdat we weten dat er maar één mes is en geen reden de controle van de prisoners. Als we de prisonermet een mes niet vinden, verhogen we een waarschuwing. Dit kan op veel verschillende manieren worden gedaan en het gebruik van returnis waarschijnlijk niet eens de beste manier, maar het is gewoon een voorbeeld om te laten zien hoe u returnte gebruiken voor het verlaten van een functie.

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

Opmerking: u zou nooit moeten doen var = find_prisoner_with_knife(), aangezien de retourwaarde niet bedoeld is om te worden gepakt.

NO returnüberhaupt

Hiermee wordt ook Noneteruggezet, maar die waarde is niet bedoeld om te worden gebruikt of betrapt. Het betekent gewoon dat de functie met succes is geëindigd. Het is eigenlijk hetzelfde als returnin voidFuncties in talen zoals C++ of Java.

In het volgende voorbeeld hebben we de naam van de persoon van de persoon ingesteld en vervolgens de functie uitgangen na het voltooien van succes.

def set_mother(person, mother):
    if is_human(person):
        person.mother = mother

Opmerking: je moet nooit var = set_mother(my_person, my_mother)doen, aangezien de geretourneerde waarde niet bedoeld is om te worden gevangen.


Antwoord 2, autoriteit 7%

Ja, ze zijn allemaal hetzelfde.

We kunnen de geïnterpreteerde machinecode bekijken om te bevestigen dat ze allemaal precies hetzelfde doen.

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      

Antwoord 3, autoriteit 3%

Ze retourneren elk dezelfde singleton None— Er is geen functioneel verschil.

Ik denk dat het redelijk idiomatisch is om de return-instructie weg te laten, tenzij je het nodig hebt om vroegtijdig uit de functie te breken (in welk geval een kale returnmeer is common), of iets anders teruggeven dan None. Het is ook logisch en lijkt idiomatisch om return Nonete schrijven wanneer het zich in een functie bevindt die een ander pad heeft dat iets anders retourneert dan None. Het expliciet uitschrijven van return Noneis een visuele aanwijzing voor de lezer dat er een andere branch is die iets interessants retourneert (en die aanroepende code zal waarschijnlijk beide typen return-waarden moeten verwerken).

Vaak worden in Python functies die Noneretourneren, gebruikt zoals void-functies in C — Hun doel is over het algemeen om te werken op de invoerargumenten op hun plaats(tenzij je globale gegevens gebruikt (huivering)). Het retourneren van Nonemaakt het meestal explicieter dat de argumenten zijn gemuteerd. Dit maakt het een beetje duidelijker waarom het logisch is om de return-instructie weg te laten vanuit het oogpunt van “taalconventies”.

Dat gezegd hebbende, als je in een codebasis werkt die al vooraf ingestelde conventies heeft rond deze dingen, zou ik zeker volgen om de codebasis uniform te houden…


Antwoord 4, autoriteit 2%

Zoals anderen hebben geantwoord, is het resultaat precies hetzelfde, Nonewordt in alle gevallen geretourneerd.

Het verschil is stilistisch, maar houd er rekening mee dat PEP8 vereist dat het gebruik consistent is:

Wees consistent in retourinstructies. Ofwel alle return statements in a
functie zou een uitdrukking moeten retourneren, of geen van hen zou moeten. indien van toepassing
return-statement retourneert een expressie, alle return-statements waarbij nee
waarde wordt geretourneerd, moet dit expliciet worden vermeld als return None, en an
expliciete return-instructie moet aanwezig zijn aan het einde van de functie
(indien bereikbaar).

Ja:

def foo(x):
    if x >= 0:
        return math.sqrt(x)
    else:
        return None
def bar(x):
    if x < 0:
        return None
    return math.sqrt(x)

Nee:

def foo(x):
    if x >= 0:
        return math.sqrt(x)
def bar(x):
    if x < 0:
        return
    return math.sqrt(x)

https://www.python.org/dev/peps /pep-0008/#programming-recommendations


Kortom, als je ooit een niet-Nonewaarde retourneert in een functie, betekent dit dat de geretourneerde waarde betekenis heeft en bedoeld is om te worden opgevangen door bellers. Dus wanneer u Noneretourneert, moet het ook expliciet zijn, om Nonein dit geval betekenis te geven, is het een van de mogelijke retourwaarden.

Als je helemaal geen return nodig hebt, werkt je functie eigenlijk als een procedure in plaats van een functie, dus voeg gewoon de return-instructie niet toe.

Als u een procedure-achtige functie schrijft en er is een mogelijkheid om eerder terug te keren (dwz u bent op dat moment al klaar en hoeft de rest van de functie niet uit te voeren), dan kunt u een lege returns om aan de lezer te signaleren dat het slechts een vroege voltooiing van de uitvoering is en de waarde Nonedie impliciet wordt geretourneerd, heeft geen betekenis en is niet bedoeld om te worden opgevangen (de procedure-achtige functie retourneert sowieso altijd None).


Antwoord 5

Qua functionaliteit zijn deze allemaal hetzelfde, het verschil tussen hen zit in de leesbaarheid en stijl van de code (wat belangrijk is om te overwegen)

Other episodes