Mam funkcję, która może zwrócić jedną z trzech rzeczy:
- sukces (
True
) - awaria (
False
) - błąd odczytu / analizy strumienia (
None
)
Moje pytanie brzmi, czy nie mam testować przeciwko, True
czy też False
jak mam zobaczyć, jaki jest wynik. Poniżej przedstawiam, jak obecnie to robię:
result = simulate(open("myfile"))
if result == None:
print "error parsing stream"
elif result == True: # shouldn't do this
print "result pass"
else:
print "result fail"
czy to naprawdę jest tak proste, jak usunięcie == True
części, czy powinienem dodać typ danych tri-bool. Nie chcę, aby simulate
funkcja zgłaszała wyjątek, ponieważ jedyne, co chcę, aby program zewnętrzny zrobił z błędem, to zarejestrowanie go i kontynuowanie.
simulate
funkcji łapię wszystkie wyjątki; Nie chcę, aby cokolwiek, co dzieje się w symulatorze, zatrzymywało działanie reszty programu (i przetwarzanie następnego elementu). Ale odpowiedzi sprawiają, że zmieniam zdanie.simulate
coś, co może złapać i spróbować ponownie, to dobrze. Ale jeśli „zawiedzie”, nie powinien powrócićNone
. Powinien po prostu zgłosić wyjątek do skryptu, który go wywołał. Tak czy inaczej,simulate
jest skończone. ZwracanieNone
nie jest tak pomocne, jak zgłoszenie odpowiedniego wyjątku - lub zezwolenie na propagację wyjątku dosimulate
skryptu wywołującego w celu obsługi.except Exception:
zamiast tego. To wychwytuje wszystkie „prawdziwe” błędy, wraz zWarning
iStopIteration
. Pozwala onKeyboardInterrupt
iSystemExit
przez chociaż. Jeśli naprawdę chcesz je złapać, prawdopodobnie najlepiej jest użyć innej, zewnętrznej try / z wyjątkiem lub innej struktury, która wyraźnie dokumentuje twoje zamiary, ponieważ nie są to „błędy”. (Ale powiedziałem "prawie nigdy" ... być może w twoim przypadku naprawdę chcesz złapać wszystko, a nawet uniemożliwić Ctrl-C lubsys.exit()
wyjście z niego itp.)Odpowiedzi:
Nie bój się Wyjątku! Wystarczy, że zalogujesz się i będziesz kontynuować program, tak łatwo, jak:
A teraz możesz mieć znacznie bogatszy typ powiadomienia z metody symulacji, co dokładnie poszło nie tak, w przypadku, gdy okaże się, że błąd / brak błędu nie jest wystarczająco informacyjny.
źródło
traceback.format_exc()
. Zobacz tę odpowiedź SO.niech to będzie proste i wyraźne. Możesz oczywiście wstępnie zdefiniować słownik.
Jeśli planujesz zmodyfikować swoją
simulate
funkcję, aby zawierała więcej kodów powrotu, utrzymanie tego kodu może stać się nieco problemem.simulate
Może również podnieść wyjątek na błąd analizy, w takim przypadku, że albo będzie go złapać tutaj albo niech propagują poziom w górę i nieco drukowanie zostanie zredukowana do jednej linii if-else.źródło
Nigdy, nigdy, nigdy nie mów
Nigdy. To szalone, ponieważ nadmiarowo powtarzasz to, co jest nadmiarowo określone jako nadmiarowa reguła warunku dla instrukcji if.
Gorzej, nigdy, nigdy, nigdy, nigdy nie mów
Masz
not
. Zapraszam do korzystania z niego.Wreszcie działanie
a == None
jest nieefektywne. Zróba is None
.None
jest specjalnym pojedynczym obiektem, może być tylko jeden. Po prostu sprawdź, czy masz ten przedmiot.źródło
True
nie jest zbędne (chociaż zgadzam się, że nie jest to rozsądne). Może to być wywołanie jakiejś__eq__
specjalnej metody, która może zrobić praktycznie wszystko.if something == True
dają inny wynik niżif something
np. Dla wartości innych niż boolowskiesomething
.2==True
daje false, podczas gdy zwraca2
wartość true;None==False
jest fałszywe, alenot None
prawdziwe!something
zwracaTrue
onbool(something)
. W takim przypadku, jeśli TYLKO chcesz sprawdzić, czysomething
ma wartośćTrue
iebool
. Następnie MUSISZ zrobićif something == True
IMO.Chciałbym podkreślić, że nawet jeśli są sytuacje, w których
if expr :
nie wystarczy, ponieważ chce się mieć pewność, żeexpr
jest,True
a nie tylko różni się od0
/None
/ cokolwiek,is
z==
tego samego powodu, o którym wspomniał S.Lott, aby go unikać== None
.Jest rzeczywiście nieco wydajniejszy i - wisienka na torcie - bardziej czytelny dla człowieka.
źródło
Uważam, że rzucenie wyjątku to lepszy pomysł na Twoją sytuację. Alternatywą będzie metoda symulacji zwracająca krotkę. Pierwsza pozycja będzie statusem, a druga wynikiem:
źródło
False
zostanie zwrócony, zostanie wydrukowany'error parsing stream'
.