Zastanawiałem się nad najlepszymi praktykami wskazywania nieprawidłowych kombinacji argumentów w Pythonie. Spotkałem kilka sytuacji, w których masz taką funkcję:
def import_to_orm(name, save=False, recurse=False):
"""
:param name: Name of some external entity to import.
:param save: Save the ORM object before returning.
:param recurse: Attempt to import associated objects as well. Because you
need the original object to have a key to relate to, save must be
`True` for recurse to be `True`.
:raise BadValueError: If `recurse and not save`.
:return: The ORM object.
"""
pass
Jedyną irytacją jest to, że każda paczka ma swoją, zwykle nieco się różni BadValueError
. Wiem, że w Javie istnieje java.lang.IllegalArgumentException
- czy dobrze wiadomo, że wszyscy będą tworzyć własne BadValueError
w Pythonie, czy jest też inna, preferowana metoda?
math.sqrt(-1)
, to błąd programowy, który i tak należy naprawić.ValueError
nie jest przeznaczony do przechwytywania podczas normalnego wykonywania programu lub może pochodzićRuntimeError
.Odziedziczyłbym po
ValueError
Czasami lepiej jest tworzyć własne wyjątki, ale dziedziczyć po wbudowanym, który jest tak blisko, jak chcesz.
Jeśli chcesz wyłapać ten konkretny błąd, dobrze jest mieć nazwę.
źródło
Myślę, że najlepszym sposobem na poradzenie sobie z tym jest sposób, w jaki sam Python sobie z tym radzi. Python podnosi błąd typu. Na przykład:
Nasz młodszy programista właśnie znalazł tę stronę w wyszukiwaniu w Google „niepoprawne argumenty wyjątku Python” i jestem zaskoczony, że oczywista (dla mnie) odpowiedź nigdy nie była sugerowana w ciągu dekady, odkąd zadano to pytanie.
źródło
int('a')
). źródłosum()
bez argumentów, co oznaczaTypeError
, ale OP zajmował się „nielegalnymi” kombinacjami wartości argumentów, gdy typy argumentów są poprawne. W tym przypadku obasave
irecurse
są boolami, ale jeślirecurse
tak,True
tosave
nie powinno byćFalse
. Jest toValueError
. Zgadzam się, że odpowiedź na jakąś interpretację tytułu pytania byłaby możliwaTypeError
, ale nie w przedstawionym przykładzie.Najczęściej widziałem wbudowane
ValueError
używane w tej sytuacji.źródło
Zależy to od problemu z argumentami.
Jeśli argument ma niewłaściwy typ, podnieś błąd TypeError. Na przykład, gdy otrzymasz ciąg zamiast jednego z tych booleanów.
Zauważ jednak, że w Pythonie rzadko przeprowadzamy takie kontrole. Jeśli argument naprawdę jest nieprawidłowy, pewna głębsza funkcja prawdopodobnie narzeka za nas. A jeśli sprawdzimy tylko wartość boolowską, być może jakiś użytkownik kodu po prostu poda jej ciąg znaków, wiedząc, że niepuste ciągi są zawsze Prawdą. Może uratować mu obsadę.
Jeśli argumenty mają niepoprawne wartości, zwiększ wartośćError. Wydaje się to bardziej odpowiednie w twoim przypadku:
Lub w tym konkretnym przypadku, wartość True rekurencji oznacza True wartość save. Ponieważ uważam to za naprawę po błędzie, możesz również złożyć skargę w dzienniku.
źródło
Nie jestem pewien, zgadzam się z dziedziczenia
ValueError
- mojej interpretacji dokumentacji jest to, żeValueError
jest tylko ma być podniesiony przez builtins ... dziedziczenie z nim lub podnosząc ją samemu wydaje się błędne.- Dokumentacja ValueError
źródło
ValueError
do tego rodzaju rzeczy, więc myślę, że próbujesz wczytywać zbyt wiele w dokumentację.Zgadzam się z sugestią Markusa dotyczącą wprowadzenia własnego wyjątku, ale tekst wyjątku powinien wyjaśniać, że problem dotyczy listy argumentów, a nie poszczególnych wartości argumentów. Zaproponowałbym:
Używane, gdy brakuje argumentów słów kluczowych wymaganych dla konkretnego wywołania lub wartości argumentów są indywidualnie ważne, ale niespójne ze sobą.
ValueError
nadal miałoby rację, gdy określony argument jest poprawnego typu, ale poza zakresem.Czy nie powinien to być standardowy wyjątek w Pythonie?
Ogólnie rzecz biorąc, chciałbym, aby styl Pythona był nieco ostrzejszy w odróżnianiu złych danych wejściowych funkcji (błąd wywołującego) od złych wyników w obrębie funkcji (moja wina). Może więc istnieć błąd BadArgumentError, aby odróżnić błędy wartości w argumentach od błędów wartości w plikach lokalnych.
źródło
KeyError
za nie znaleziono słowa kluczowego (ponieważ brakujące jawne słowo kluczowe jest semantycznie identyczne ze słowem, w**kwargs
którym brakuje tego klucza).