Otrzymuję ostrzeżenie, że BaseException.message jest przestarzała w Pythonie 2.6, gdy używam następującego wyjątku zdefiniowanego przez użytkownika:
class MyException(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return repr(self.message)
To jest ostrzeżenie:
DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
self.message = message
Co w tym złego? Co muszę zmienić, aby pozbyć się ostrzeżenia o wycofaniu?
python
exception
deprecated
opuszczony
źródło
źródło
Odpowiedzi:
Rozwiązanie - prawie bez kodowania
Po prostu odziedzicz swoją klasę wyjątku od
Exception
i przekaż wiadomość jako pierwszy parametr do konstruktoraPrzykład:
Możesz użyć
str(my)
lub (mniej eleganckie),my.args[0]
aby uzyskać dostęp do wiadomości niestandardowej.tło
W nowszych wersjach Pythona (od 2.6) mamy dziedziczyć nasze niestandardowe klasy wyjątków z Exception, które ( począwszy od Pythona 2.5 ) dziedziczy po BaseException. Tło zostało szczegółowo opisane w PEP 352 .
__str__
i__repr__
są już zaimplementowane w znaczący sposób, szczególnie w przypadku tylko jednego argumentu (który może być użyty jako komunikat).Nie trzeba powtarzać
__str__
lub__init__
realizacja lub utwórz_get_message
sugerowane przez innych.źródło
str
przerw, jeśli wyjątek został skonstruowany z argumentem Unicode:str(MyException(u'\xe5'))
raisesUnicodeEncodeError
. Używanieunicode
zamiast tego równieżstr
nie jest niezawodne, ponieważunicode(MyException('\xe5'))
wywołuje UnicodeDecodeError. Czy to oznacza, że jeśli nie wiem z góry, czy argument jest,str
czyunicode
muszę użyć tego,.args[0]
co wcześniej użyłem.message
?.message
w naszym projekcie na.args[0]
, a to nie sprawiło nam żadnych problemów.Tak, jest przestarzały w Pythonie 2.6, ponieważ odchodzi w Pythonie 3.0
Klasa BaseException nie zapewnia już sposobu przechowywania komunikatów o błędach. Będziesz musiał sam to wdrożyć. Możesz to zrobić z podklasą, która używa właściwości do przechowywania wiadomości.
Mam nadzieję że to pomoże
źródło
@property
składni, gdy naprawdę potrzebujesz hermetyzacji.@property
aby wyłączyć ostrzeżenie o wycofaniu.To jest Twoja klasa w stylu Python2.6. Nowy wyjątek przyjmuje dowolną liczbę argumentów.
źródło
Jak powtórzyć ostrzeżenie
Pozwól, że wyjaśnię problem, ponieważ nie można tego powtórzyć za pomocą przykładowego kodu pytania, spowoduje to powtórzenie ostrzeżenia w Pythonie 2.6 i 2.7, jeśli masz włączone ostrzeżenia (za pomocą
-W
flagi ,PYTHONWARNINGS
zmiennej środowiskowej lub modułu ostrzeżeń ):Przestań używać
.message
Wolę
repr(error)
, która zwraca ciąg zawierający nazwę typu błędu, repr komunikatu, jeśli taki istnieje, oraz repr pozostałych argumentów.Eliminacja ostrzeżenia podczas dalszego używania
.message
A sposobem pozbycia się tego
DeprecationWarning
jest utworzenie podklasy wbudowanego wyjątku zgodnie z zamierzeniami projektantów Pythona:uzyskanie tylko
.message
atrybutu bezerror.message
Jeśli wiesz, że do wyjątku był jeden argument, komunikat, i właśnie tego chcesz, lepiej jest unikać atrybutu komunikatu i po prostu wziąć
str
błąd. Powiedz o podklasieException
:I użycie:
Zobacz także tę odpowiedź:
Właściwy sposób na deklarowanie niestandardowych wyjątków we współczesnym Pythonie?
źródło
O ile wiem, po prostu użycie innej nazwy dla atrybutu wiadomości pozwala uniknąć konfliktu z klasą bazową, a tym samym zatrzymuje ostrzeżenie o wycofaniu:
Wydaje mi się, że to hack.
Może ktoś może wyjaśnić, dlaczego ostrzeżenie jest wyświetlane, nawet jeśli podklasa wyraźnie definiuje atrybut komunikatu. Jeśli klasa bazowa nie ma już tego atrybutu, nie powinno być problemu.
źródło
Kontynuując od odpowiedzi geekQ , preferowana zamiana kodu zależy od tego, co musisz zrobić:
Czasami wyjątki mają więcej niż jeden argument, więc
my.args[0]
nie gwarantuje się dostarczenia wszystkich istotnych informacji.Na przykład:
Drukuje jako wyjście:
Jest to jednak kompromis zależny od kontekstu, ponieważ na przykład:
źródło
str(my)
zamiastmy.message
.Porada dotycząca używania str (myexception) prowadzi do problemów z Unicode w Pythonie 2.7, np .:
:(
działa zgodnie z oczekiwaniami i jest preferowane w przypadkach, gdy część zawartości ciągu błędu zawiera dane wejściowe użytkownika
źródło
Post pzrq mówi, aby użyć:
To było dokładnie to, czego potrzebowałem.
(Jeśli pracujesz w środowisku Unicode, wygląda na to, że:
będzie działać i wygląda na to, że działa dobrze w środowisku innym niż Unicode)
Pzrq powiedział wiele innych dobrych rzeczy, ale prawie przegapiłem ich odpowiedź z powodu wszystkich dobrych rzeczy. Ponieważ nie mam 50 punktów, nie mogę komentować ich odpowiedzi, aby spróbować zwrócić uwagę na proste rozwiązanie, które działa, a ponieważ nie mam 15, nie mogę zagłosować na tę odpowiedź, ale mogę publikować (wydaje się być zacofany, ale no cóż) - tak oto piszę - pewnie stracę za to punkty ...
Ponieważ moim celem jest zwrócenie uwagi na odpowiedź pzrq, nie glazuruj i nie przegap tego we wszystkich poniższych. kilka pierwszych linijek tego posta jest najważniejszych.
Moja historia:
Problem, dla którego tu przyszedłem, polegał na tym, że jeśli chcesz złapać wyjątek z zajęć, nad którymi nie masz kontroli - co wtedy ??? Z pewnością nie zamierzam tworzyć podklas wszystkich możliwych klas, których używa mój kod, aby móc uzyskać komunikat ze wszystkich możliwych wyjątków!
Używałem:
który, jak wszyscy teraz wiemy, daje ostrzeżenie OP, o które pytano (które mnie tu przywiodło), a to, co podaje pzrq jako sposób na zrobienie tego:
nie.
Nie jestem w środowisku Unicode, ale odpowiedź jjc sprawiła, że zacząłem się zastanawiać, więc musiałem spróbować. W tym kontekście staje się to:
który, ku mojemu zaskoczeniu, działał dokładnie tak, jak str (e) - więc teraz tego używam.
Nie wiem, czy „str (e) / unicode (e)” jest „zatwierdzoną metodą Pythona” i prawdopodobnie dowiem się, dlaczego to nie jest dobre, kiedy dojdę do 3.0, ale można mieć nadzieję, że umiejętność obsługi nieoczekiwany wyjątek (*) bez umierania, a mimo to otrzymanie z niego pewnych informacji nigdy nie zniknie ...
(*) Hmm. „nieoczekiwany wyjątek” - wydaje mi się, że się jąkałem!
źródło