Le code suivant examine le comportement de la méthode float () code> lors d'une édition d'un symbole non ASCII:
import sys
try:
float(u'\xbd')
except ValueError as e:
print sys.getdefaultencoding() # in my system, this is 'ascii'
print e[0].decode('latin-1') # u'invalid literal for float(): ' followed by the 1/2 (one half) character
print unicode(e[0]) # raises "UnicodeDecodeError: 'ascii' codec can't decode byte 0xbd in position 29: ordinal not in range(128)"
4 Réponses :
Le codage ASCII n'inclut que les octets avec des valeurs Le seul symbole, cependant, ne fait pas partie de Le jeu de caractères ASCII, donc lorsque Python tente de coder ce symbole en ASCII, il ne peut rien faire mais échouer. P> strong> Voici ce qui se passe (je suppose que nous parlons de cpython ): p> alors, L'argument à cette exception est une chaîne p> C'est bien; Un message d'exception est, après tout, une chaîne. Ce n'est que lorsque vous essayez de décoder cette chaîne, à l'aide de l'encodage par défaut ASCII, que cela transforme un problème. P> p> <= 127 code>. La gamme de caractères représentés par ces octets est identique dans la plupart des codages; En d'autres termes, "A" est
chr (65) code> en ASCII, en latin-1, dans UTF-8, etc.
float (u '\ xbd') code> mène à
pyflat_fromstring code> dans FloatObject.c être appelé. Cette fonction, donnant un objet Unicode, à tour d'appel
pyunicode_encodedecimal code> dans UnicodeObject.c appelé. D'écrémer sur le code, je comprends que cette fonction transforme l'objet Unicode en une chaîne en remplaçant tous les caractères avec un codePoint d'unicode
<256 code> avec l'octet de cette valeur, c'est-à-dire le personnage d'un demi-caractère, ayant Le codePoint 189 est transformé en
chr (89) code>. p>
pyfloat_fromstring code> est-ce que son travail est d'habitude. En ce moment, cela fonctionne avec une chaîne ordinaire, qui contenant un octet de plage non-ASCII. Cela ne se soucie pas de cela; Il trouve juste un octet qui n'est pas un chiffre, une période ou similaire, il augmente l'erreur de valeur. P>
Cela ne répond pas à ma question, j'ai peur. J'ai légèrement édité le texte original pour être plus clair. (J'ai changé la question en gras). Je crois comprendre que ASCII ne peut pas offrir une représentation pour le caractère étrange. Mon problème est que E [0] semble être codé en latin-1, même si ASCII est le codage par défaut. Mon raisonnement est que le flotteur () aurait dû soulever une exception codée par ASCII (ou unicode). Cependant, c'est en latin-1 ou quelque chose de similaire à la place. Il aurait dû tenter de coder le message d'erreur en ASCII et a échoué, élever une UnicodeDecodeError en premier lieu, pas une ValueError.
Cela aurait dû être chr (189) code> je suppose
D'expérimenter avec votre code de code, il semblerait que j'ai le même comportement sur ma plate-forme (PY2.6 sur OS X 10.5). P>
Puisque vous avez établi que E [0] est codé avec update: strong> il semble donc que E [0] n'a pas de codage valide. Définitivement pas latin-1 code>, le moyen correct de la convertir
unicode code> est pour faire
.decode ('latin -1 ') code> et pas em>
unicode (e [0]) code>. P>
latin-1 code>. À cause de cela, comme mentionné ailleurs dans les commentaires, vous devrez appeler
REC (E [0]) code> Si vous devez afficher ce message d'erreur avec une exception en cascade. P >
Ce n'est pas codé comme latin-1, il suffit de convertir des valeurs ordinales unicode aux octets.
e [0] n'est pas codé avec latin-1; Il arrive tellement que l'octet \ xbd, lorsqu'il est décodé comme latin-1, est le caractère U + 00bd.
La conversion se produit dans Premièrement, la chaîne Unicode doit être convertie en une chaîne d'octets. Ceci est effectué en utilisant qui est implémenté dans Le formatage de l'instruction La mise en forme de l'erreur est la suivante: p> où Objets / floatobject.c p> p>
pyunicode_encodedecimal () code>: p>
UnicdeObject.c code>. Il n'effectue aucune sorte de conversion de jeu de caractères, il écrit juste des octets avec des valeurs égales aux ordinaux unicode de la chaîne. Dans ce cas, U + 00bd -> 0xbd. P>
s code> contient la chaîne d'octets créée plus tôt.
pyos_snprintf () code> écrit une chaîne d'octets et
s code> est une chaîne d'octets, il suffit donc de l'inclure directement. P> P>
Devrait-il être considéré comme un bug en python? Mon raisonnement: si float () a reçu une chaîne unicode, elle devrait lancer une exception décrite unicode si le message va inclure l'entrée. Sinon, des exceptions ne peuvent pas être traitées en toute sécurité, comme l'exemple de l'exemple.
Je pense que l'appeler un bug est juste - l'erreur Messaeg devrait probablement contenir REC (V) code> au lieu de
STR (s) code>, car connaissez la valeur d'entrée d'origine est plus utile. que la version codée décimale.
Très bonne question!
J'ai pris la liberté de creuser dans le code source de Python, qui est une simple commande sur la configuration correcte des distributions Linux ( sacrément em>, John Millikin m'a battu. C'est vrai, voir, il laisse tous les points de code UNICODE <256 en place, qui sont les Les caractères latin-1, basés sur la compatibilité en arrière d'Unicode. p> addendum p> Avec cela en place, vous pouvez vérifier en essayant d'autres caractères non latins-1, il va lancer Exception différente: p> apt-get source python2.5 code>) < / p>
pyunicode_encodedecimal code> est la réponse qu'il l'est ici ici: p>