Czytałem jakiś kod źródłowy i w kilku miejscach widziałem użycie assert
.
Co to dokładnie znaczy? Jakie jest jego użycie?
python
assert
assertions
Hossein
źródło
źródło
Odpowiedzi:
assert
Oświadczenie istnieje w prawie każdym języku programowania. Pomaga wykryć problemy na wczesnym etapie programu, gdzie przyczyna jest wyraźna, a nie później jako efekt uboczny innej operacji.Kiedy to zrobisz ...
... każesz programowi przetestować ten warunek i natychmiast wywołać błąd, jeśli warunek jest fałszywy.
W Pythonie odpowiada to mniej więcej tak:
Wypróbuj w powłoce Pythona:
Asercje mogą zawierać opcjonalny komunikat i można je wyłączyć podczas uruchamiania interpretera.
Aby wydrukować wiadomość, jeśli asercja się nie powiedzie:
Czy nie używać nawiasów, aby wywołać
assert
jak funkcja. To jest oświadczenie. Jeśli to zrobiszassert(condition, message)
, uruchomiszassert
z(condition, message)
krotką jako pierwszym parametrem.Jeśli chodzi o ich wyłączanie, podczas działania
python
w trybie zoptymalizowanym, gdzie__debug__
jestFalse
, instrukcje aser będą ignorowane. Wystarczy przekazać-O
flagę:Zobacz tutaj odpowiednią dokumentację.
źródło
if not condition: raise AssertError()
, dlaczego powinienem użyć asercji? Czy są jakieś warunki, w których twierdzenie jest lepsze niż bycie krótszymif not condition
stwierdzeniem?if
). Przeczytaj dokumentację, aby uzyskać więcej informacji :)assert
, ale po przeczytaniu wszystkich odpowiedzi całkowicie nie mam nic, czego chcę!Uważaj na nawiasy. Jak już wspomniano powyżej, w Pythonie 3
assert
nadal znajduje się stwierdzenie , więc analogicznie doprint(..)
, można ekstrapolować to samoassert(..)
lubraise(..)
nie należy.Jest to ważne, ponieważ:
nie zadziała, w przeciwieństwie do
Pierwszym powodem, dla którego pierwszy nie zadziała, jest
bool( (False, "Houston we've got a problem") )
ocenaTrue
.W oświadczeniu
assert(False)
są to po prostu nadmiarowe nawiasy wokółFalse
, które oceniają ich zawartość. Ale zassert(False,)
nawiasami są teraz krotki, a niepuste krotki mająTrue
wartość logiczną.źródło
assert (2 + 2 = 5), "Houston we've got a problem"
powinno być ok, tak?assert (2 + 2 = 5), "Houston we've got a problem"
nie będzie działać ... ale nie ma to nic wspólnego z instrukcją assert, co jest w porządku. Twój stan nie będzie działać, ponieważ nie jest to stan. Brakuje sekundy=
.Jak zauważyły inne odpowiedzi,
assert
przypomina rzucanie wyjątku, jeśli dany warunek nie jest spełniony. Ważną różnicą jest to, że instrukcje aser są ignorowane, jeśli skompilujesz kod z opcją optymalizacji-O
. Dokumentacja mówi, żeassert expression
może być lepiej opisane jako równoważneMoże to być przydatne, jeśli chcesz dokładnie przetestować swój kod, a następnie wydać wersję zoptymalizowaną, gdy będziesz zadowolony, że żadna z twoich asercji nie zawiodła - gdy optymalizacja jest włączona,
__debug__
zmienna staje się False i warunki przestają być oceniane. Ta funkcja może Cię również złapać, jeśli polegasz na twierdzeniach i nie zdajesz sobie sprawy, że zniknęły.źródło
if Not Error: raise Exception(“ this is a error”)
? W ten sposób program nadal wyświetli źródło błędu, gdy użytkownik go uruchomi.assert
instrukcji? Zakłada się tutaj, że kiedy program zostanie wydany użytkownikowi końcowemu, używasz flagi -O, zakładając w ten sposób, że wszystkie błędy zostały usunięte. Dlatego też każdy błąd lub awaria programu wynika z danych wejściowych do programu, które są ważne zgodnie z umową, ale nie mogą być obsługiwane przez program. Powinien więc ostrzec użytkownika jako takiego.Celem asercji w Pythonie jest informowanie programistów o niemożliwych do naprawienia błędach w programie.
Asercje nie są przeznaczone do sygnalizowania oczekiwanych warunków błędu, takich jak „nie znaleziono pliku”, w których użytkownik może podjąć działania naprawcze (lub po prostu spróbować ponownie).
Innym sposobem na to jest stwierdzenie, że asercje są wewnętrznymi samokontrolami w twoim kodzie. Działają, deklarując niektóre warunki jako niemożliwe w twoim kodzie. Jeśli te warunki się nie utrzymają, oznacza to błąd w programie.
Jeśli twój program nie zawiera błędów, te warunki nigdy nie wystąpią. Ale jeśli wystąpi jeden z nich , program ulegnie awarii z błędem asercji, informującym dokładnie, który warunek „niemożliwy” został wywołany. Dzięki temu znacznie łatwiej jest wyśledzić i naprawić błędy w swoich programach.
Oto podsumowanie z samouczka na temat twierdzeń Pythona, które napisałem:
źródło
assert
oświadczenie i kiedy go używać. Próbuję zrozumieć kilka terminów wprowadzonych w tym artykule.assert store.product_exists(product_id), 'Unknown product id'
nie jest dobrą praktyką, ponieważ jeśli debugowanie zostanie wyłączone, touser
nawet jeśli nieadmin
będzie w stanie usunąć produktu. Czy uważają Państwo,assert user.is_admin()
jakounrecoverable
błąd? Dlaczego to nie jestself-check
?assert statement
, czy nieprice
można również uznać za dane wejściowe użytkownika? Dlaczego uważasz zaassert user.is_admin()
walidację danych, ale nieassert price
?Inni już dali ci linki do dokumentacji.
Możesz wypróbować następujące opcje w interaktywnej powłoce:
Pierwsze zdanie nic nie robi, a drugie podnosi wyjątek. Jest to pierwsza wskazówka: aserty są przydatne do sprawdzania warunków, które powinny być prawdziwe w danej pozycji kodu (zwykle na początku (warunki wstępne) i na końcu funkcji (warunki dodatkowe)).
Aserty są w rzeczywistości ściśle powiązane z programowaniem na podstawie umowy, co jest bardzo przydatną praktyką inżynierską:
http://en.wikipedia.org/wiki/Design_by_contract .
źródło
Z dokumentów:
Tutaj możesz przeczytać więcej: http://docs.python.org/release/2.5.2/ref/assert.html
źródło
Instrukcja assert ma dwie formy.
Prosta forma
assert <expression>
, jest odpowiednikiemRozszerzona forma
assert <expression1>, <expression2>
, jest równoważnaźródło
Asercje to systematyczny sposób sprawdzania, czy wewnętrzny stan programu jest zgodny z oczekiwaniami programisty, w celu wykrycia błędów. Zobacz przykład poniżej.
źródło
Oto prosty przykład, zapisz to w pliku (powiedzmy b.py)
a wynik kiedy
$python b.py
źródło
jeśli instrukcja po potwierdzeniu jest prawdziwa, program kontynuuje działanie, ale jeśli instrukcja po potwierdzeniu jest fałszywa, wówczas program podaje błąd. Proste.
na przykład:
źródło
assert
Oświadczenie istnieje w prawie każdym języku programowania. Pomaga wykryć problemy na wczesnym etapie programu, gdzie przyczyna jest wyraźna, a nie później jako efekt uboczny innej operacji. Zawsze oczekująTrue
warunku.Kiedy robisz coś takiego:
Mówisz programowi, aby przetestował ten warunek i natychmiast wywołał błąd, jeśli jest fałszywy.
W Pythonie
assert
wyrażenie jest równoważne z:Możesz użyć wyrażenia rozszerzonego, aby przekazać opcjonalny komunikat :
Wypróbuj w interpreterie języka Python:
Jest kilka ostrzeżeń, które należy zobaczyć przed użyciem ich głównie dla tych, którzy uważają, że przełączają się między instrukcjami
assert
iif
. Celem jest użycie,assert
gdy program weryfikuje warunek i zwraca wartość, która powinna natychmiast zatrzymać program, zamiast wybierać alternatywny sposób obejścia błędu:1. Nawiasy
Jak zapewne zauważyłeś,
assert
instrukcja wykorzystuje dwa warunki. Dlatego nie używaj nawiasów, aby je globalizować jako oczywiste porady. Jeśli to zrobisz:Przykład:
Będziesz działał
assert
z(condition, message)
parametrem, który reprezentuje krotkę jako pierwszy parametr, a dzieje się tak, ponieważ niepuste krotki w Pythonie są zawszeTrue
. Możesz jednak zrobić to oddzielnie bez problemu:Przykład:
2. Cel debugowania
Jeśli zastanawiasz się, kiedy użyć
assert
instrukcji. Weź przykład wykorzystany w prawdziwym życiu:* Gdy twój program ma tendencję do kontrolowania każdego parametru wprowadzonego przez użytkownika lub cokolwiek innego:
* Kolejny przypadek dotyczy matematyki, gdy 0 lub wartość dodatnia jako współczynnik lub stała na pewnym równaniu:
* lub nawet prosty przykład implementacji boolean:
3. Przetwarzanie lub walidacja danych
Niezwykle ważne jest, aby nie polegać na
assert
instrukcji do przetwarzania danych lub sprawdzania poprawności danych, ponieważ tę instrukcję można wyłączyć przy inicjalizacji języka Python za pomocą-O
lub-OO
flagi - odpowiednio wartości 1, 2 i 0 (domyślnie) - lubPYTHONOPTIMIZE
zmiennej środowiskowej .Wartość 1:
* twierdzenia są wyłączone;
* pliki kodu bajtowego są generowane przy użyciu
.pyo
rozszerzenia zamiast.pyc
;*
sys.flags.optimize
jest ustawiony na 1 (True
);* i
__debug__
jest ustawiony naFalse
;Wartość 2: wyłącza jeszcze jedną rzecz
* dokumenty są wyłączone;
Dlatego używanie
assert
instrukcji do sprawdzania poprawności rodzaju oczekiwanych danych jest niezwykle niebezpieczne, co sugeruje nawet pewne problemy z bezpieczeństwem. Następnie, jeśli potrzebujesz zweryfikować jakieś pozwolenie, polecamraise AuthError
zamiast tego. Jako warunek wstępny, programistaassert
jest powszechnie używany przez programistów w bibliotekach lub modułach, które nie wymagają bezpośredniej interakcji użytkownika.źródło
Jak streszczono zwięźle na Wiki Wiki :
Za pomocą
assert
instrukcji można udokumentować zrozumienie kodu w określonym punkcie programu. Na przykład można udokumentować założenia lub gwarancje dotyczące danych wejściowych (warunki wstępne), stanu programu (niezmienniki) lub wyników (warunki dodatkowe).Jeśli twoje twierdzenie kiedykolwiek się nie powiedzie, jest to ostrzeżenie dla ciebie (lub twojego następcy), że twoje zrozumienie programu było błędne, kiedy go napisałeś, i że prawdopodobnie zawiera błąd.
Aby uzyskać więcej informacji, John Regehr ma wspaniały wpis na blogu na temat korzystania z asercji , który dotyczy również
assert
instrukcji Python .źródło
Jeśli kiedykolwiek chcesz dokładnie wiedzieć, co funkcja zarezerwowana robi w Pythonie, wpisz
help(enter_keyword)
Upewnij się, że jeśli wprowadzasz zarezerwowane słowo kluczowe, które wpisujesz jako ciąg.
źródło
Aser Python jest w zasadzie pomocą do debugowania, która testuje warunki wewnętrznej kontroli twojego kodu. Assert sprawia, że debugowanie jest naprawdę łatwe, gdy kod wpada w niemożliwe przypadki brzegowe. Zapewnij sprawdź te niemożliwe przypadki.
Załóżmy, że istnieje funkcja obliczania ceny produktu po rabacie:
w tym przypadku cena ze zniżką nigdy nie może być mniejsza niż 0 i większa od rzeczywistej ceny. Tak więc, w przypadku naruszenia powyższego warunku, assert wywołuje błąd asercji, który pomaga deweloperowi zidentyfikować, że stało się coś niemożliwego.
Mam nadzieję, że to pomoże :)
źródło
assert
jest przydatny w kontekście debugowania, ale nie należy na nim polegać poza kontekstem debugowania.Moje krótkie wyjaśnienie to:
assert
podnosi,AssertionError
jeśli wyrażenie jest fałszywe, w przeciwnym razie po prostu kontynuuje kod, a jeśli jest przecinek, czymkolwiek będzieAssertionError: whatever after comma
, a kod jest jak:raise AssertionError(whatever after comma)
Powiązany samouczek na ten temat:
źródło
assert
, ale nie kiedy używać (lub nie używać)assert
; również zauważyć, żeassert
może być wyłączona, jeśli__debug__
znaczyFalse
byłaby przydatna.W programie Pycharm, jeśli użyjesz
assert
goisinstance
do zadeklarowania typu obiektu, pozwoli ci on uzyskać dostęp do metod i atrybutów obiektu nadrzędnego podczas kodowania, automatycznie się uzupełni.Załóżmy na przykład, że
self.object1.object2
jestMyClass
obiektem.źródło
Jak napisano w innych odpowiedziach,
assert
instrukcje służą do sprawdzania stanu programu w danym punkcie.Nie powtórzę tego, co zostało powiedziane na temat powiązanej wiadomości, nawiasów lub
-O
opcji i__debug__
stałej. Sprawdź także dokument, aby uzyskać informacje z pierwszej ręki. Skoncentruję się na twoim pytaniu: do czego służyassert
? Mówiąc dokładniej, kiedy (a kiedy nie) należy użyćassert
?Te
assert
stwierdzenia są przydatne do debugowania programu, ale zniechęcony do sprawdzenia danych wprowadzonych przez użytkownika. Używam następującej zasady: zachowaj twierdzenia, aby wykryć, że taka sytuacja nie powinna się zdarzyć . Wprowadzane przez użytkownika dane mogą być niepoprawne, np. Hasło jest za krótkie, ale nie jest to przypadek, który nie powinien się zdarzyć . Jeśli średnica koła nie jest dwa razy większa niż jego promień, oznacza to, że nie powinno się to zdarzyć .Moim zdaniem najciekawsze użycie
assert
inspirowane jest programowaniem na podstawie umowy, jak opisano przez B. Meyera w [Object-Oriented Software Construction] ( https://www.eiffel.org/doc/eiffel/Object-Oriented_Software_Construction% 2C_2nd_Edition ) i zaimplementowane w [języku programowania Eiffel] ( https://en.wikipedia.org/wiki/Eiffel_(programming_language) ). Nie można w pełni emulować programowania na podstawie umowy za pomocąassert
instrukcji, ale warto zachować intencję.Oto przykład. Wyobraź sobie, że musisz napisać
head
funkcję (jak [head
funkcja w Haskell] ( http://www.zvon.org/other/haskell/Outputprelude/head_f.html )). Podana specyfikacja to: „jeśli lista nie jest pusta, zwróć pierwszą pozycję na liście”. Spójrz na następujące implementacje:I
(Tak, można to zapisać jako
return xs[0] if xs else None
, ale nie o to chodzi) .Jeśli lista nie jest pusta, obie funkcje mają ten sam wynik i ten wynik jest poprawny:
Dlatego obie implementacje są (mam nadzieję) poprawne. Różnią się, gdy próbujesz zabrać nagłówek pustej listy:
Ale:
Ponownie obie implementacje są poprawne, ponieważ nikt nie powinien przekazywać pustej listy do tych funkcji (jesteśmy poza specyfikacją ). To niepoprawne połączenie, ale jeśli wykonasz takie połączenie, wszystko może się zdarzyć. Jedna funkcja wywołuje wyjątek, druga zwraca specjalną wartość. Najważniejsze jest: nie możemy polegać na tym zachowaniu . Jeśli
xs
jest pusty, to zadziała:Spowoduje to jednak awarię programu:
Aby uniknąć niespodzianek, chciałbym wiedzieć, kiedy przekazuję nieoczekiwany argument funkcji. Innymi słowy: chciałbym wiedzieć, kiedy obserwowalne zachowanie nie jest wiarygodne, ponieważ zależy to od implementacji, a nie od specyfikacji. Oczywiście mogę przeczytać specyfikację, ale programiści nie zawsze dokładnie czytają dokumenty.
Wyobraź sobie, że mam sposób, aby wstawić specyfikację do kodu, aby uzyskać następujący efekt: gdy naruszę specyfikację, np. Przekazując pustą listę
head
, otrzymam ostrzeżenie. Byłoby to bardzo pomocne w napisaniu poprawnego (tj. Zgodnego ze specyfikacją) programu. I tamassert
wkracza na scenę:I
Teraz mamy:
I:
Zauważ, że
head1
wyrzuca anAssertionError
, a nie anIndexError
. Jest to ważne, ponieważ anAssertionError
nie jest żadnym błędem środowiska wykonawczego: sygnalizuje naruszenie specyfikacji. Chciałem ostrzeżenia, ale pojawia się błąd. Na szczęście mogę wyłączyć kontrolę (korzystając z-O
opcji), ale na własne ryzyko. Zrobię to, awaria jest naprawdę droga i mam nadzieję na najlepsze. Wyobraź sobie, że mój program jest osadzony w statku kosmicznym, który podróżuje przez czarną dziurę. Wyłączę asercje i mam nadzieję, że program jest wystarczająco solidny, aby nie powodować awarii tak długo, jak to możliwe.Ten przykład dotyczył tylko warunków wstępnych,
assert
ponieważ można użyć do sprawdzenia warunków dodatkowych (wartość zwracana i / lub stan) i niezmienników (stan klasy). Pamiętaj, że sprawdzanie warunków dodatkowych i niezmienników za pomocąassert
może być kłopotliwe:Nie będziesz mieć czegoś tak wyrafinowanego jak Eiffel, ale możesz jednak poprawić ogólną jakość programu.
Podsumowując,
assert
stwierdzenie to wygodny sposób na wykrycie takiej sytuacji, która nie powinna się zdarzyć . Naruszenie specyfikacji (np. Przekazanie pustej listyhead
) jest pierwszą klasą, nie powinno się zdarzyć . Dlatego chociażassert
oświadczenie może być użyte do wykrycia każdej nieoczekiwanej sytuacji, jest to uprzywilejowany sposób zapewnienia spełnienia specyfikacji. Po wstawieniuassert
instrukcji do kodu reprezentujących specyfikację możemy mieć nadzieję, że poprawiłeś jakość programu, ponieważ zostaną zgłoszone niepoprawne argumenty, niepoprawne wartości zwracane, niepoprawne stany klasy ...źródło
format: assert Expression [, argumenty] Gdy aser napotka instrukcję, Python ocenia wyrażenie. Jeśli instrukcja nie jest prawdziwa, zgłaszany jest wyjątek (assertionError). Jeśli asercja się nie powiedzie, Python użyje ArgumentExpression jako argumentu dla AssertionError. Wyjątki AssertionError mogą być wychwytywane i obsługiwane jak każdy inny wyjątek za pomocą instrukcji try-wyjątek, ale jeśli nie zostaną obsłużone, zakończą program i wygenerują śledzenie. Przykład:
Wykonanie powyższego kodu powoduje następujący wynik:
źródło
Może być użyty, aby zapewnić przekazanie parametrów w wywołaniu funkcji.
źródło
if not user_key: raise ValueError()
sprawdź tutaj ostatnie 2 akapity: wiki.python.org/moin/UsingAssertionsEffectivelyassert
nie powinien być używany do sprawdzania poprawności danych wejściowych, ponieważ sprawdzanie poprawności zostanie usunięte, jeśli tak__debug__
jestFalse
. Również stosowanie asercji do celów innych niż debugowanie może spowodować, że ludzie złapią wynikoweAssertionError
s, co może utrudnić debugowanie zamiast go zmniejszyć.źródło
Zasadniczo znaczenie słowa kluczowego assert polega na tym, że jeśli warunek nie jest spełniony, to przez asertywność lub w przeciwnym razie kontynuuje na przykład w pythonie.
kod-1
WYNIK:
kod-2
WYNIK:
źródło
assert
, ale nie odpowiada, kiedy należy użyć (lub nie)assert
.