zwrot, zwrot brak, i nie ma powrotu w ogóle?
Rozważmy trzy funkcje:
def my_func1():
print "Hello World"
return None
def my_func2():
print "Hello World"
return
def my_func3():
print "Hello World"
Wszystkie wydają się nie zwracać żadnych. Czy są jakieś różnice między zachowaniem zwracanej wartości tych funkcji? Czy są jakieś powody, by preferować jedno z drugim?
5 answers
W rzeczywistym zachowaniu, nie ma różnicy. Wszyscy wracają None
i tyle. Jednak jest na to czas i miejsce.
Poniższe instrukcje są w zasadzie jak różne metody powinny być używane( lub przynajmniej jak zostałem nauczony, że powinny być używane), ale nie są to bezwzględne zasady, więc możesz je mieszać, jeśli uważasz, że jest to konieczne.
Używanie return None
To mówi, że funkcja rzeczywiście ma zwracać wartość do późniejszego użycia, a w tym przypadku zwraca None
. Wartość None
może być użyta gdzie indziej. return None
nie jest nigdy używane, jeśli nie ma innych możliwych wartości zwracanych z funkcji.
W poniższym przykładzie zwracamy person
's mother
Jeśli person
jest człowiekiem. Jeśli nie jest to człowiek, zwracamy None
, Ponieważ person
nie ma mother
(Załóżmy, że nie jest to zwierzę lub coś).
def get_mother(person):
if is_human(person):
return person.mother
else:
return None
Za Pomocą return
Jest to używane z tego samego powodu co break
w pętlach. Wartość zwracana nie ma znaczenia i chcesz tylko zamknąć całą funkcję. Jest to niezwykle przydatne w niektórych miejscach, mimo że nie potrzebujesz go tak często.
Mamy 15 prisoners
i wiemy, że jeden z nich ma nóż. Przechodzimy przez każdy prisoner
jeden po drugim, aby sprawdzić, czy mają nóż. Jeśli uderzymy osobę nożem, możemy po prostu wyjść z funkcji, ponieważ wiemy, że jest tylko jeden nóż i nie ma powodu, aby sprawdzić resztę prisoners
. Jeśli nie znajdziemy prisoner
z nożem, ogłosimy alarm. Można to zrobić w wielu różne sposoby i używanie return
prawdopodobnie nie jest nawet najlepszym sposobem, ale jest to tylko przykład, aby pokazać, jak używać return
do wyjścia z funkcji.
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()
Uwaga: nigdy nie powinieneś tego robić var = find_prisoner_with_knife()
, ponieważ wartość zwracana nie jest przeznaczona do przechwytywania.
Użycie nie return
w ogóle
Zwróci również None
, ale ta wartość nie jest przeznaczona do użycia ani przechwycenia. Oznacza to po prostu, że funkcja zakończyła się pomyślnie. Jest to w zasadzie to samo co return
w void
funkcje w językach takich jak C++ czy Java.
W poniższym przykładzie ustawiamy imię matki osoby, a następnie funkcja kończy się po pomyślnym zakończeniu.
def set_mother(person, mother):
if is_human(person):
person.mother = mother
Uwaga: nigdy nie powinieneś tego robić var = set_mother(my_person, my_mother)
, ponieważ wartość zwracana nie jest przeznaczona do przechwytywania.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-18 11:26:25
Tak, wszystkie są takie same.
Możemy przejrzeć zinterpretowany kod maszynowy, aby potwierdzić, że wszyscy robią dokładnie to samo.
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-08 18:36:09
Każdy zwraca ten sam singleton None
- nie ma różnicy funkcjonalnej.
Myślę, że rozsądnie idiomatycznym jest opuszczenie return
, chyba że potrzebujesz go, aby wcześniej wyłączyć funkcję (w tym przypadku nagie return
jest bardziej powszechne), lub zwrócenie czegoś innego niż None
. Zapis return None
ma również sens i wydaje się idiomatyczny, gdy jest w funkcji, która ma inną ścieżkę, która zwraca coś innego niż None
. Wypisanie return None
jawnie jest wizualny sygnał do czytnika, że jest inna gałąź, która zwraca coś ciekawszego (i że kod wywołujący prawdopodobnie będzie musiał obsłużyć oba typy zwracanych wartości).
Często w Pythonie funkcje zwracające None
są używane jak void
funkcje w C - ich celem jest generalnie operowanie na argumentach wejściowych zamiast (chyba że używasz danych globalnych ( shudders)). Zwracanie None
Zwykle uwidacznia, że argumenty zostały zmutowane. To sprawia, że jest trochę bardziej jasne, dlaczego ma sens pomijanie return
z punktu widzenia "konwencji językowych".
To powiedziawszy, jeśli pracujesz w bazie kodu, która ma już wstępnie ustawione konwencje wokół tych rzeczy, zdecydowanie zastosowałbym się do tego, aby pomóc bazie kodu pozostać jednolitym...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-09 02:24:34
Jak inni odpowiedzieli, wynik jest dokładnie taki sam, None
jest zwracany we wszystkich przypadkach.
Różnica jest stylistyczna, ale proszę zauważyć, że PEP8 wymaga, aby użycie było spójne:
Bądź spójny w wyrażeniach zwrotnych. Albo wszystkie polecenia return w funkcja powinna zwracać wyrażenie lub żadne z nich nie powinno. Jeśli w ogóle Instrukcja return zwraca wyrażenie, każde polecenie return, gdzie nie zwracana wartość powinna być jawnie podać jako return None, oraz jawne polecenie return powinno być obecne na końcu funkcji (jeśli osiągalny).
Tak:
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)
Nie:
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
Zasadniczo, jeśli kiedykolwiek zwrócisz wartość nie - None
w Funkcji, Oznacza to, że zwracana wartość ma znaczenie i ma zostać przechwycona przez wywołujące. Więc kiedy wrócisz None
, musi być również explicit, aby przekazać None
w tym przypadku ma znaczenie, jest jedną z możliwych wartości zwracanych.
Jeśli w ogóle nie potrzebujesz return, funkcja działa w zasadzie jako procedura zamiast funkcji, więc nie dołączaj instrukcji return
.
Jeśli piszesz funkcję podobną do procedury i istnieje możliwość wcześniejszego powrotu (tzn. już to zrobiłeś i nie musisz wykonywać pozostałej funkcji) możesz użyć empty an return
s, aby zasygnalizować reader jest to tylko wczesne zakończenie wykonania i wartość None
zwracana domyślnie nie ma żadnego znaczenia i nie jest przeznaczona do przechwycenia(funkcja podobna do procedury zawsze zwraca None
w każdym razie).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-04 23:36:46
Pod względem funkcjonalności wszystkie są takie same, różnica między nimi polega na czytelności kodu i stylu (co należy wziąć pod uwagę)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-31 20:13:17