it-swarm.com.de

Gibt es irgendwelche Stichwörter, die in Python 2.6 unicode_literals verwenden?

Wir haben unsere Codebasis bereits unter Python 2.6 ausgeführt. Um uns auf Python 3.0 vorzubereiten, haben wir begonnen, Folgendes hinzuzufügen:

 aus __zukunft__ importieren Sie Unicode_Literals 

in unsere .py-Dateien (wenn wir sie ändern). Ich frage mich, ob jemand anderes dies getan hat und auf nicht offensichtliche Fallstricke gestoßen ist (vielleicht nach einem langen Debugging).

99

Die Hauptquelle der Probleme, die ich mit Unicode-Strings hatte, ist das Mischen von utf-8-codierten Strings mit Unicode-Strings.

Betrachten Sie zum Beispiel die folgenden Skripts.

zwei

# encoding: utf-8
name = 'helló wörld from two'

ein.py

# encoding: utf-8
from __future__ import unicode_literals
import two
name = 'helló wörld from one'
print name + two.name

Die Ausgabe von python one.py lautet:

Traceback (most recent call last):
  File "one.py", line 5, in <module>
    print name + two.name
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 4: ordinal not in range(128)

In diesem Beispiel ist two.name eine utf-8-codierte Zeichenfolge (kein Unicode), da unicode_literals nicht importiert wurde, und one.name ist eine Unicode-Zeichenfolge. Wenn Sie beide mischen, versucht Python, die codierte Zeichenfolge zu decodieren (vorausgesetzt, es ist ascii), und konvertiert sie in Unicode und schlägt fehl. Es würde funktionieren, wenn Sie print name + two.name.decode('utf-8') hätten.

Das Gleiche kann passieren, wenn Sie einen String kodieren und versuchen, ihn später zu mischen. __ Dies funktioniert beispielsweise:

# encoding: utf-8
html = '<html><body>helló wörld</body></html>'
if isinstance(html, unicode):
    html = html.encode('utf-8')
print 'DEBUG: %s' % html

Ausgabe:

DEBUG: <html><body>helló wörld</body></html>

Nach dem Hinzufügen von import unicode_literals wird jedoch NICHT

# encoding: utf-8
from __future__ import unicode_literals
html = '<html><body>helló wörld</body></html>'
if isinstance(html, unicode):
    html = html.encode('utf-8')
print 'DEBUG: %s' % html

Ausgabe:

Traceback (most recent call last):
  File "test.py", line 6, in <module>
    print 'DEBUG: %s' % html
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 16: ordinal not in range(128)

Es schlägt fehl, da 'DEBUG: %s' eine Unicode-Zeichenfolge ist und Python daher versucht, html zu decodieren. Es gibt einige Möglichkeiten, den Druck zu korrigieren, indem Sie entweder print str('DEBUG: %s') % html oder print 'DEBUG: %s' % html.decode('utf-8') ausführen.

Ich hoffe, dies hilft Ihnen dabei, die möglichen Gotchas bei der Verwendung von Unicode-Strings zu verstehen.

101
Koba

Auch in 2.6 (vor Python 2.6.5 RC1 +) spielen Unicode-Literale Nice nicht mit Schlüsselwortargumenten ( issue4978 ):

Der folgende Code funktioniert beispielsweise ohne Unicode_Literals, schlägt jedoch mit TypeError fehl: keywords must be string, wenn Unicode_Literals verwendet wird.

  >>> def foo(a=None): pass
  ...
  >>> foo(**{'a':1})
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
      TypeError: foo() keywords must be strings
16
mfazekas

Ich habe festgestellt, dass, wenn Sie die unicode_literals-Direktive hinzufügen, auch Folgendes hinzugefügt werden sollte:

 # -*- coding: utf-8

in der ersten oder zweiten Zeile Ihre .py-Datei. Ansonsten Zeilen wie:

 foo = "barré"

führen Sie zu einem Fehler wie:

 SyntaxError: Nicht-ASCII-Zeichen '\ xc3' in Datei mumble.py in Zeile 198, 
 aber keine Kodierung angegeben; siehe http://www.python.org/peps/pep-0263.html 
 für Details
13

Berücksichtigen Sie auch, dass unicode_literaleval() betrifft, aber nicht repr() (ein asymmetrisches Verhalten, das imho ein Fehler ist), d. H. eval(repr(b'\xa4')) ist nicht gleich b'\xa4' (wie bei Python 3).

Im Idealfall wäre der folgende Code für alle Kombinationen von unicode_literals und Python {2.7, 3.x} eine Invariante, die immer funktionieren sollte:

from __future__ import unicode_literals

bstr = b'\xa4'
assert eval(repr(bstr)) == bstr # fails in Python 2.7, holds in 3.1+

ustr = '\xa4'
assert eval(repr(ustr)) == ustr # holds in Python 2.7 and 3.1+

Die zweite Behauptung funktioniert, da repr('\xa4') in Python 2.7 zu u'\xa4' ausgewertet wird.

8
hvr

Da sind mehr.

Es gibt Bibliotheken und Builtins, die Strings erwarten, die Unicode nicht zulassen.

Zwei Beispiele:

eingebaut:

myenum = type('Enum', (), enum)

(etwas esotisch) funktioniert nicht mit unicode_literals: type () erwartet einen String.

bibliothek:

from wx.lib.pubsub import pub
pub.sendMessage("LOG MESSAGE", msg="no go for unicode literals")

funktioniert nicht: Die Wx-Pubsub-Bibliothek erwartet einen String-Nachrichtentyp.

Ersteres ist esoterisch und leicht zu reparieren

myenum = type(b'Enum', (), enum)

letzteres ist jedoch verheerend, wenn Ihr Code mit Aufrufen von pub.sendMessage () (die meine ist) voll ist.

Dang es, nicht wahr?!?

5
GreenAsJade

Click löst Unicode-Ausnahmen überall aus, wenn ein Modul mit from __future__ import unicode_literals importiert wird, wo Sie click.echo verwenden. Es ist ein Albtraum…

0
Sardathrion