Conversion d’une exception en chaîne dans Python 3

Quelqu’un at-il une idée, pourquoi ce code Python 3.2

try: raise Exception('X') except Exception as e: print("Error {0}".format(str(e))) 

fonctionne sans problème (en dehors de l’encodage Unicode dans Windows Shell: /), mais cela

 try: raise Exception('X') except Exception as e: print("Error {0}".format(str(e, encoding = 'utf-8'))) 

jette TypeError: contraignant à str: nécessite des octets, bytearray ou object de type tampon, Exception trouvée ?

Comment convertir une erreur en une chaîne avec un codage personnalisé?

modifier

Cela ne fonctionne pas non plus, s’il y a \ u2019 dans le message:

 try: raise Exception(msg) except Exception as e: b = bytes(str(e), encoding = 'utf-8') print("Error {0}".format(str(b, encoding = 'utf-8'))) 

Mais pourquoi ne peut pas str () convertir une exception en interne en octets?

Dans Python 3.x, str(e) devrait être capable de convertir toute Exception dans une chaîne, même si elle contient des caractères Unicode.

Donc, à moins que votre exception ne retourne un tableau d’octets codé en UTF-8 dans sa __str__() , str(e, 'utf-8') ne fonctionnera pas comme prévu (il essaiera d’interpréter une chaîne de caractères Unicode un tableau d’octets codé en UTF-8 …)

Je suppose que votre problème n’est pas str() mais print() (c’est-à-dire l’étape qui convertit la chaîne Python Unicode en quelque chose qui est sauvegardé sur votre console). Voir cette réponse pour les solutions: Python, Unicode et la console Windows

Essayez ceci, ça devrait marcher.

 try: raise Exception('X') except Exception as e: print("Error {0}".format(str(e.args[0])).encode("utf-8")) 

Considérant que vous n’avez qu’un message dans votre tuple interne.

Dans Python3, ssortingng n’a pas d’atsortingbut tel que l’encodage. C’est toujours unicode en interne. Pour les chaînes codées, il existe des tableaux d’octets:

 s = "Error {0}".format(str(e)) # ssortingng utf8str = s.encode("utf-8") # byte array, representing utf8-encoded text 

Dans Python 3, vous êtes déjà dans “l’espace unicode” et n’avez pas besoin d’encodage. Selon ce que vous voulez réaliser, vous devriez faire la conversion immédiatement avant de faire des choses.

Par exemple, vous pouvez convertir tout cela en bytes() , mais plutôt dans la direction

 bytes("Error {0}".format(str(e)), encoding='utf-8') 

.

Il y a une conversion indépendante de la version ici:

 # from the `six` library import sys PY2 = sys.version_info[0] == 2 if PY2: text_type = unicode binary_type = str else: text_type = str binary_type = bytes def exc2str(e): if e.args and isinstance(e.args[0], binary_type): return e.args[0].decode('utf-8') return text_type(e) 

et teste pour cela:

 def test_exc2str(): a = u"\u0856" try: raise ValueError(a) except ValueError as e: assert exc2str(e) == a assert isinstance(exc2str(e), text_type) try: raise ValueError(a.encode('utf-8')) except ValueError as e: assert exc2str(e) == a assert isinstance(exc2str(e), text_type) try: raise ValueError() except ValueError as e: assert exc2str(e) == '' assert isinstance(exc2str(e), text_type)