Recebo um aviso de que BaseException.message está obsoleto no Python 2.6 quando uso a seguinte exceção definida pelo usuário:
class MyException(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return repr(self.message)
Este é o aviso:
DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
self.message = message
O que há de errado nisso? O que preciso alterar para me livrar do aviso de obsolescência?
python
exception
deprecated
desolado
fonte
fonte
Respostas:
Solução - quase sem necessidade de codificação
Apenas herde sua classe de exceção
Exception
e passe a mensagem como o primeiro parâmetro para o construtorExemplo:
Você pode usar
str(my)
ou (menos elegante)my.args[0]
para acessar a mensagem personalizada.fundo
Nas versões mais recentes do Python (da 2.6), devemos herdar nossas classes de exceção personalizadas da Exception, que (a partir do Python 2.5 ) herda da BaseException. O plano de fundo é descrito em detalhes no PEP 352 .
__str__
e__repr__
já foram implementados de maneira significativa, especialmente no caso de apenas um argumento (que pode ser usado como mensagem).Você não precisa repetir
__str__
ou__init__
implementar ou criar_get_message
conforme sugerido por outras pessoas.fonte
str
quebras se a exceção foi construída com um argumento unicode:str(MyException(u'\xe5'))
raisesUnicodeEncodeError
. Usar emunicode
vez destr
não é infalível porqueunicode(MyException('\xe5'))
gera UnicodeDecodeError. Isso significa que, se eu não souber antecipadamente se o argumento éstr
ouunicode
, tenho que usar.args[0]
onde usei anteriormente.message
?.message
em nosso projeto por.args[0]
e isso não causou nenhum problema para nós.Sim, está obsoleto no Python 2.6 porque está desaparecendo no Python 3.0
A classe BaseException não fornece mais uma maneira de armazenar mensagens de erro. Você terá que implementá-lo você mesmo. Você pode fazer isso com uma subclasse que usa uma propriedade para armazenar a mensagem.
Espero que isto ajude
fonte
@property
sintaxe quando realmente precisar de encapsulamento.@property
para desativar o aviso de reprovação .Esta é sua classe no estilo Python2.6. A nova exceção leva um número arbitrário de argumentos.
fonte
Como replicar o aviso
Deixe-me esclarecer o problema, como não é possível replicar isso com o código de exemplo da pergunta, ele replicará o aviso no Python 2.6 e 2.7, se você tiver avisos ativados (por meio do
-W
sinalizador , daPYTHONWARNINGS
variável de ambiente ou do módulo de avisos ):Pare de usar
.message
Eu prefiro
repr(error)
, que retorna uma string que contém o nome do tipo de erro, a repr da mensagem, se houver, e a repr dos argumentos restantes.Eliminando o aviso enquanto ainda estiver usando
.message
E a maneira como você se livrar do
DeprecationWarning
é a subclasse uma exceção incorporado como os designers Python destina:ficando apenas o
.message
atributo semerror.message
Se você sabe que houve um argumento, uma mensagem, para a exceção e é isso que você deseja, é preferível evitar o atributo de mensagem e apenas aceitar
str
o erro. Diga para uma subclasseException
:E uso:
Veja também esta resposta:
Maneira correta de declarar exceções personalizadas no Python moderno?
fonte
Tanto quanto posso dizer, o simples uso de um nome diferente para o atributo de mensagem evita o conflito com a classe base e, portanto, interrompe o aviso de descontinuação:
Parece um truque para mim.
Talvez alguém possa explicar por que o aviso é emitido, mesmo quando a subclasse define explicitamente um atributo da mensagem. Se a classe base não tiver mais esse atributo, não deverá haver um problema.
fonte
Continuando com a resposta do geekQ , a substituição preferida do código depende do que você precisa fazer:
Às vezes, as exceções têm mais de um argumento, então
my.args[0]
não há garantia de fornecer todas as informações relevantes.Por exemplo:
Imprime como saída:
No entanto, é uma troca sensível ao contexto, porque, por exemplo:
fonte
str(my)
vez demy.message
.O conselho para usar str (myexception) leva a problemas unicode no python 2.7, por exemplo:
:(
funciona como esperado e é preferido nos casos em que parte do conteúdo da sequência de erros inclui entrada do usuário
fonte
A publicação de pzrq diz para usar:
Era exatamente disso que eu precisava.
(Se você estiver em um ambiente unicode, parece que:
funcionará e parece funcionar bem em um ambiente não unicode)
Pzrq disse muitas outras coisas boas, mas eu quase perdi a resposta devido a todas as coisas boas. Como não tenho 50 pontos, não posso comentar a resposta deles para tentar chamar a atenção para a solução simples que funciona, e como não tenho 15, não posso votar nessa resposta, mas posso postar (parece atrasado, mas oh bem) - então aqui estou postando - provavelmente perdem pontos por isso ...
Como o meu objetivo é chamar a atenção para a resposta do pzrq, por favor, não encha o olho e perca tudo isso abaixo. as primeiras linhas deste post são as mais importantes.
Minha história:
O problema para o qual vim aqui foi se você deseja capturar uma exceção de uma classe que não tem controle - e então ??? Certamente não vou subclassificar todas as classes possíveis que meu código usa para tentar obter uma mensagem de todas as possíveis exceções!
Eu estava usando:
que, como todos sabemos agora, dá o aviso que o OP perguntou sobre (o que me trouxe aqui), e este, que o pzrq fornece como uma maneira de fazê-lo:
nao fiz.
Não estou em um ambiente unicode, mas a resposta de jjc me fez pensar, então tive que tentar. Nesse contexto, isso se torna:
que, para minha surpresa, funcionou exatamente como str (e) - então agora é isso que estou usando.
Não sei se 'str (e) / unicode (e)' é a 'maneira Python aprovada', e provavelmente vou descobrir por que isso não é bom quando chego ao 3.0, mas esperamos que a capacidade de lidar com um exceção inesperada (*) sem morrer e ainda assim obter algumas informações, nunca desaparecerá ...
(*) Hmm. "exceção inesperada" - acho que gaguejei!
fonte