In Python 3 sind alle Zeichenfolgen Sequenzen von Unicode-Zeichen. Es gibt einen bytesTyp, der Rohbytes enthält.
In Python 2 kann eine Zeichenfolge vom Typ stroder vom Typ sein unicode. Mit Code können Sie Folgendes feststellen:
def whatisthis(s):if isinstance(s, str):print"ordinary string"elif isinstance(s, unicode):print"unicode string"else:print"not a string"
Dies unterscheidet nicht zwischen "Unicode oder ASCII". Es werden nur Python-Typen unterschieden. Eine Unicode-Zeichenfolge kann aus reinen Zeichen im ASCII-Bereich bestehen, und ein Bytestring kann ASCII-, codierte Unicode- oder sogar nicht-textuelle Daten enthalten.
In Python 2 strist nur eine Folge von Bytes. Python weiß nicht, wie es codiert ist. Der unicodeTyp ist die sicherere Methode zum Speichern von Text. Wenn Sie dies besser verstehen möchten, empfehle ich http://farmdev.com/talks/unicode/ .
In Python 3 strist es wie in Python 2 unicodeund wird zum Speichern von Text verwendet. Was strin Python 2 genannt wurde, heißt bytesin Python 3.
Wie man erkennt, ob eine Byte-Zeichenfolge gültig ist utf-8 oder ascii
Sie können anrufen decode. Wenn eine UnicodeDecodeError-Ausnahme ausgelöst wird, war sie nicht gültig.
>>> u_umlaut = b'\xc3\x9c'# UTF-8 representation of the letter 'Ü'>>> u_umlaut.decode('utf-8')
u'\xdc'>>> u_umlaut.decode('ascii')Traceback(most recent call last):File"<stdin>", line 1,in<module>UnicodeDecodeError:'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
Nur als Referenz für andere Leute - str.decode existiert nicht in Python 3. Sieht aus wie Sie müssen unicode(s, "ascii")oder so
Shadow
3
Entschuldigung, ich meintestr(s, "ascii")
Shadow
1
Dies ist nicht genau für Python 3
ProsperousHeart
2
@ProsperousHeart Aktualisiert, um Python 3 abzudecken. Und um zu versuchen, den Unterschied zwischen Bytestrings und Unicode-Strings zu erklären.
Mikel
44
In Python 3.x sind alle Zeichenfolgen Sequenzen von Unicode-Zeichen. und die isinstance-Prüfung für str (was standardmäßig Unicode-String bedeutet) sollte ausreichen.
isinstance(x, str)
In Bezug auf Python 2.x scheinen die meisten Leute eine if-Anweisung zu verwenden, die zwei Prüfungen enthält. eine für str und eine für unicode.
Wenn Sie jedoch überprüfen möchten, ob Sie ein 'stringartiges' Objekt mit einer einzigen Anweisung haben, können Sie Folgendes tun:
Das ist falsch. In Python 2.7 isinstance(u"x",basestring)kehrt zurück True.
PythonNut
11
@ PythonNut: Ich glaube, das war der Punkt. Die Verwendung von isinstance (x, basestring) reicht aus, um die oben genannten unterschiedlichen Doppeltests zu ersetzen.
KQ.
5
Es ist in vielen Fällen nützlich, aber offensichtlich nicht das, was der Fragesteller meinte.
Mhsmith
3
Dies ist die Antwort auf die Frage. Alle anderen haben das, was OP gesagt hat, falsch verstanden und allgemeine Antworten zur Typprüfung in Python gegeben.
Fiatjaf
1
Beantwortet die Frage von OP nicht. Der Titel der Frage (allein) KANN so interpretiert werden, dass diese Antwort richtig ist. OP sagt jedoch in der Beschreibung der Frage ausdrücklich "finde heraus, welche", und diese Antwort spricht das nicht an.
MD004
31
Unicode ist keine Kodierung - um Kumar McMillan zu zitieren:
Wenn ASCII, UTF-8 und andere Byte-Zeichenfolgen "Text" sind ...
Diese Folien sind wahrscheinlich die beste Einführung in Unicode, die mir bisher begegnet ist
Jonny,
23
Wenn Ihr Code sowohl mit Python 2 als auch mit Python 3 kompatibel sein muss , können Sie Dinge wie isinstance(s,bytes)oder isinstance(s,unicode)ohne Umbruch weder in try / exception noch in einem Python-Versionstest direkt verwenden , da er bytesin Python 2 unicodeundefiniert und in Python 3 undefiniert ist .
Es gibt einige hässliche Problemumgehungen. Sehr hässlich ist es, den Namen des Typs zu vergleichen , anstatt den Typ selbst zu vergleichen. Hier ist ein Beispiel:
# convert bytes (python 3) or unicode (python 2) to strif str(type(s))=="<class 'bytes'>":# only possible in Python 3
s = s.decode('ascii')# or s = str(s)[2:-1]elif str(type(s))=="<type 'unicode'>":# only possible in Python 2
s = str(s)
Eine wohl etwas weniger hässliche Problemumgehung besteht darin, die Python-Versionsnummer zu überprüfen, z.
if sys.version_info >=(3,0,0):# for Python 3if isinstance(s, bytes):
s = s.decode('ascii')# or s = str(s)[2:-1]else:# for Python 2if isinstance(s, unicode):
s = str(s)
Diese sind beide unpythonisch und die meiste Zeit gibt es wahrscheinlich einen besseren Weg.
Der bessere Weg ist wahrscheinlich zu verwenden sixund gegen six.binary_typeundsix.text_type
Ian Clelland
1
Sie können Typ (en) .__ name__ verwenden , um Typnamen zu prüfen .
Paulo Freitas
Ich bin mir des Anwendungsfalls für dieses Codebit nicht ganz sicher, es sei denn, es liegt ein logischer Fehler vor. Ich denke, der Python 2-Code sollte ein "Nicht" enthalten. Ansonsten konvertieren Sie alles in Unicode-Strings für Python 3 und das Gegenteil für Python 2!
Oligofren
Ja, Oligofren, das ist es, was es tut. Die internen Standardzeichenfolgen sind Unicode in Python 3 und ASCII in Python 2. Die Codefragmente konvertieren also Text in den internen Standardzeichenfolgentyp (sei es Unicode oder ASCII).
Dave Burton
12
verwenden:
import six
if isinstance(obj, six.text_type)
Innerhalb der sechs Bibliotheken wird es dargestellt als:
if PY3:
string_types = str,else:
string_types = basestring,
es sollte sein if isinstance(obj, six.text_type) . Aber ja das ist imo die richtige Antwort.
Karantan
Beantwortet die Frage von OP nicht. Der Titel der Frage (allein) KANN so interpretiert werden, dass diese Antwort richtig ist. OP sagt jedoch in der Beschreibung der Frage ausdrücklich "finde heraus, welche", und diese Antwort spricht das nicht an.
MD004
4
Beachten Sie, dass es in Python 3 nicht fair ist, Folgendes zu sagen:
strs sind UTFx für jedes x (z. B. UTF8)
strs sind Unicode
strs sind geordnete Sammlungen von Unicode-Zeichen
Pythons strTyp ist (normalerweise) eine Folge von Unicode-Codepunkten, von denen einige Zeichen zugeordnet sind.
Selbst unter Python 3 ist es nicht so einfach, diese Frage zu beantworten, wie Sie sich vorstellen können.
Ein offensichtlicher Weg, um auf ASCII-kompatible Zeichenfolgen zu testen, ist ein Codierungsversuch:
"Hello there!".encode("ascii")#>>> b'Hello there!'"Hello there... ☃!".encode("ascii")#>>> Traceback (most recent call last):#>>> File "", line 4, in <module>#>>> UnicodeEncodeError: 'ascii' codec can't encode character '\u2603' in position 15: ordinal not in range(128)
Der Fehler unterscheidet die Fälle.
In Python 3 gibt es sogar einige Zeichenfolgen, die ungültige Unicode-Codepunkte enthalten:
"Hello there!".encode("utf8")#>>> b'Hello there!'"\udcc3".encode("utf8")#>>> Traceback (most recent call last):#>>> File "", line 19, in <module>#>>> UnicodeEncodeError: 'utf-8' codec can't encode character '\udcc3' in position 0: surrogates not allowed
Die gleiche Methode zur Unterscheidung wird verwendet.
Dies kann jemand anderem helfen. Ich habe mit dem Testen des Zeichenfolgentyps der Variablen s begonnen, aber für meine Anwendung war es sinnvoller, s einfach als utf-8 zurückzugeben. Der Prozess, der return_utf aufruft, weiß dann, womit er es zu tun hat, und kann die Zeichenfolge entsprechend behandeln. Der Code ist nicht makellos, aber ich beabsichtige, dass er Python-Versionsunabhängig ist, ohne dass ein Versionstest durchgeführt oder sechs importiert werden. Bitte kommentieren Sie den folgenden Beispielcode mit Verbesserungen, um anderen Personen zu helfen.
def return_utf(s):if isinstance(s, str):return s.encode('utf-8')if isinstance(s,(int, float, complex)):return str(s).encode('utf-8')try:return s.encode('utf-8')exceptTypeError:try:return str(s).encode('utf-8')exceptAttributeError:return s
exceptAttributeError:return s
return s # assume it was already utf-8
Du mein Freund hast es verdient, die richtige Antwort zu sein! Ich benutze Python 3 und hatte immer noch Probleme, bis ich diesen Schatz gefunden habe!
Mnnsr
2
Sie könnten den Universal Encoding Detector verwenden , aber beachten Sie, dass er Ihnen nur die bestmögliche Vermutung gibt, nicht die tatsächliche Codierung, da es beispielsweise unmöglich ist, die Codierung eines Strings "abc" zu kennen. Sie müssen Codierungsinformationen an anderer Stelle abrufen, z. B. verwendet das HTTP-Protokoll dafür den Content-Type-Header.
Ein einfacher Ansatz besteht darin, zu überprüfen, ob unicodees sich um eine integrierte Funktion handelt. Wenn ja, befinden Sie sich in Python 2 und Ihre Zeichenfolge ist eine Zeichenfolge. Um sicherzustellen, dass alles in unicodeeinem ist, kann man:
import builtins
i ='cats'if'unicode'in dir(builtins):# True in python 2, False in 3
i = unicode(i)
{UnicodeDecodeError} 'ascii' codec can't decode byte 0xc2
Antworten:
In Python 3 sind alle Zeichenfolgen Sequenzen von Unicode-Zeichen. Es gibt einen
bytes
Typ, der Rohbytes enthält.In Python 2 kann eine Zeichenfolge vom Typ
str
oder vom Typ seinunicode
. Mit Code können Sie Folgendes feststellen:Dies unterscheidet nicht zwischen "Unicode oder ASCII". Es werden nur Python-Typen unterschieden. Eine Unicode-Zeichenfolge kann aus reinen Zeichen im ASCII-Bereich bestehen, und ein Bytestring kann ASCII-, codierte Unicode- oder sogar nicht-textuelle Daten enthalten.
quelle
Wie man erkennt, ob ein Objekt eine Unicode-Zeichenfolge oder eine Byte-Zeichenfolge ist
Sie können
type
oder verwendenisinstance
.In Python 2:
In Python 2
str
ist nur eine Folge von Bytes. Python weiß nicht, wie es codiert ist. Derunicode
Typ ist die sicherere Methode zum Speichern von Text. Wenn Sie dies besser verstehen möchten, empfehle ich http://farmdev.com/talks/unicode/ .In Python 3:
In Python 3
str
ist es wie in Python 2unicode
und wird zum Speichern von Text verwendet. Wasstr
in Python 2 genannt wurde, heißtbytes
in Python 3.Wie man erkennt, ob eine Byte-Zeichenfolge gültig ist utf-8 oder ascii
Sie können anrufen
decode
. Wenn eine UnicodeDecodeError-Ausnahme ausgelöst wird, war sie nicht gültig.quelle
unicode(s, "ascii")
oder sostr(s, "ascii")
In Python 3.x sind alle Zeichenfolgen Sequenzen von Unicode-Zeichen. und die isinstance-Prüfung für str (was standardmäßig Unicode-String bedeutet) sollte ausreichen.
In Bezug auf Python 2.x scheinen die meisten Leute eine if-Anweisung zu verwenden, die zwei Prüfungen enthält. eine für str und eine für unicode.
Wenn Sie jedoch überprüfen möchten, ob Sie ein 'stringartiges' Objekt mit einer einzigen Anweisung haben, können Sie Folgendes tun:
quelle
isinstance(u"x",basestring)
kehrt zurückTrue
.Unicode ist keine Kodierung - um Kumar McMillan zu zitieren:
Lesen Sie McMillans Unicode In Python, einem vollständig entmystifizierten Vortrag von PyCon 2008, der die Dinge viel besser erklärt als die meisten verwandten Antworten zu Stack Overflow.
quelle
Wenn Ihr Code sowohl mit Python 2 als auch mit Python 3 kompatibel sein muss , können Sie Dinge wie
isinstance(s,bytes)
oderisinstance(s,unicode)
ohne Umbruch weder in try / exception noch in einem Python-Versionstest direkt verwenden , da erbytes
in Python 2unicode
undefiniert und in Python 3 undefiniert ist .Es gibt einige hässliche Problemumgehungen. Sehr hässlich ist es, den Namen des Typs zu vergleichen , anstatt den Typ selbst zu vergleichen. Hier ist ein Beispiel:
Eine wohl etwas weniger hässliche Problemumgehung besteht darin, die Python-Versionsnummer zu überprüfen, z.
Diese sind beide unpythonisch und die meiste Zeit gibt es wahrscheinlich einen besseren Weg.
quelle
six
und gegensix.binary_type
undsix.text_type
verwenden:
Innerhalb der sechs Bibliotheken wird es dargestellt als:
quelle
if isinstance(obj, six.text_type)
. Aber ja das ist imo die richtige Antwort.Beachten Sie, dass es in Python 3 nicht fair ist, Folgendes zu sagen:
str
s sind UTFx für jedes x (z. B. UTF8)str
s sind Unicodestr
s sind geordnete Sammlungen von Unicode-ZeichenPythons
str
Typ ist (normalerweise) eine Folge von Unicode-Codepunkten, von denen einige Zeichen zugeordnet sind.Selbst unter Python 3 ist es nicht so einfach, diese Frage zu beantworten, wie Sie sich vorstellen können.
Ein offensichtlicher Weg, um auf ASCII-kompatible Zeichenfolgen zu testen, ist ein Codierungsversuch:
Der Fehler unterscheidet die Fälle.
In Python 3 gibt es sogar einige Zeichenfolgen, die ungültige Unicode-Codepunkte enthalten:
Die gleiche Methode zur Unterscheidung wird verwendet.
quelle
Dies kann jemand anderem helfen. Ich habe mit dem Testen des Zeichenfolgentyps der Variablen s begonnen, aber für meine Anwendung war es sinnvoller, s einfach als utf-8 zurückzugeben. Der Prozess, der return_utf aufruft, weiß dann, womit er es zu tun hat, und kann die Zeichenfolge entsprechend behandeln. Der Code ist nicht makellos, aber ich beabsichtige, dass er Python-Versionsunabhängig ist, ohne dass ein Versionstest durchgeführt oder sechs importiert werden. Bitte kommentieren Sie den folgenden Beispielcode mit Verbesserungen, um anderen Personen zu helfen.
quelle
Sie könnten den Universal Encoding Detector verwenden , aber beachten Sie, dass er Ihnen nur die bestmögliche Vermutung gibt, nicht die tatsächliche Codierung, da es beispielsweise unmöglich ist, die Codierung eines Strings "abc" zu kennen. Sie müssen Codierungsinformationen an anderer Stelle abrufen, z. B. verwendet das HTTP-Protokoll dafür den Content-Type-Header.
quelle
Für py2 / py3-Kompatibilität einfach verwenden
import six if isinstance(obj, six.text_type)
quelle
Ein einfacher Ansatz besteht darin, zu überprüfen, ob
unicode
es sich um eine integrierte Funktion handelt. Wenn ja, befinden Sie sich in Python 2 und Ihre Zeichenfolge ist eine Zeichenfolge. Um sicherzustellen, dass alles inunicode
einem ist, kann man:quelle