Iteration über Python 3 bytes <-> Python 2 str...

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Code: Alles auswählen

data = b'\x1e\x07\x00'
print(type(data))
print(repr(data))
for item in data:
    print(repr(item))
Liefert mit Python 2 das:

Code: Alles auswählen

<type 'str'>
'\x1e\x07\x00'
'\x1e'
'\x07'
'\x00'
und mit Python 3 das:

Code: Alles auswählen

<class 'bytes'>
b'\x1e\x07\x00'
30
7
0
Das finde ich sehr merkwürdig. Ich hätte sowas erwartet:

Code: Alles auswählen

<class 'bytes'>
b'\x1e\x07\x00'
b'\x1e'
b'\x07'
b'\x00'
Da muß man Aufpassen, wenn man über bytes iteriert, das man plötzlich mit nackten Zahlen hantiert :(

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

@jens: Es ist halt sinnvoller über Zahlen zu iterieren. Was hätte denn dort geliefert werden sollen? Bytearrays der Länge 1? Das wäre ja noch merkwürdiger.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Es ist aber irgendwie eine verstecke Umwandlung. Ich hätte das lieber explizit gemacht.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hab was bei http://stackoverflow.com/questions/1426 ... in-python3 zu gefunden.

Darin ist http://legacy.python.org/dev/peps/pep-0467/ erwähnt.
Damit gibt es ein iterbytes() was dann so aussehen könnte:

Code: Alles auswählen

for item in data.iterbytes():
    print(repr(item))
Dann kommt das raus:

Code: Alles auswählen

b'\x1e'
b'\x07'
b'\x00'

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@jens: die (Geschmacks)Frage ist, was ist 1 Byte, eine Zahl oder ein Zeichen. Um es deutlicher von Schriftzeichen abzugrenzen, haben sich die Python-3 Macher halt für die Zahl entschieden. Damit geht auch sowas:

Code: Alles auswählen

data = bytes([30,7,0])
BlackJack

@jens: Das ist keine versteckte Umwandlung. Zwischen *was* denn? Der Datentyp heisst `bytes`! Das ist *keine* Zeichenkette. Wenn Du über Zeichen iterieren möchtest, dann verwende `str` und nicht `bytes`. Bytes sind Zahlwerte zwischen 0 und 255, wenn die als Zeichen iteriert würden, *das* wäre eine (ungewollte) Umwandlung. Und mit welcher Kodierung sollten denn Bytewerte über 127 umgewandelt werden?
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Das ganze ist halt doof, wenn man Py2 und 3 unterstützen will :K

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

@jens: Ach wer will das denn schon. Python 2.7 funktioniert doch prima. 3.x braucht kein Mensch. :twisted:
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

BlackJack hat geschrieben:@jens: Das ist keine versteckte Umwandlung. Zwischen *was* denn? Der Datentyp heisst `bytes`! Das ist *keine* Zeichenkette.
Ich iteriere über "type bytes" und erhalte "type integer" Das ist doch schon was anderes, auch wenn man beide in das jeweilige andere umwandeln kann...

Wie kann man das am besten in Py 2 und 3 machen?
In Py2 auch immer in Zahlenlisten umwandeln? oder in Py3 die zahlen zu bytes wandeln?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

jens hat geschrieben:Wie kann man das am besten in Py 2 und 3 machen?
In Py2 auch immer in Zahlenlisten umwandeln? oder in Py3 die zahlen zu bytes wandeln?
Wobei man kann ja ganz Allgemein zwei Strategien fahren:

1. Alles wie in Py2 machen und ausnahmen für Py3 machen...
2. anders herum: Wie in Py3 vorgesehen machen und ausnahmen für Py2 machen...

Ich denke ich werde auf 2. setzten...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

@jens: Was ist das denn für eine Argumentation? Du iterierst über ein Containerobjekt. Du beschwerst Dich doch auch nicht das man beim Iterieren über Listen nicht grundsätzlich Listen bekommt sondern halt Werte/Typen die da drin stecken. Wenn Du über `bytes` iterierst, müsstest Du nach Deiner Logik also etwas vom Typ `byte` bekommen. Und was erwartet man üblicherweise von einem Byte? Richtig, das es sich verhält wie eine Zahl zwischen 0 und 255 (oder -128 bis 127). Das ist jedenfalls bei den üblichen Programmiersprachen die einen Byte-Typ haben so. Und weil `int`\s diese Anforderung schon erfüllen macht es halt keinen Sinn extra einen `byte`-Typ einzuführen.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@jens: Wenn es dir um die textuelle Darstellung beim Iterieren geht (d.h. Interpretation der Bytewerte als einzelne Zeichen, notwendigerweise aus einem definierten Zeichensatz), dann nutze halt für Strings in Python 2.x grundsätzlich Unicode. Dann dürftest du für beide Python-Zweige ein gleiches Verhalten beim Iterieren haben.

EDIT: Und dass die Ergebnisse unter Python 2.x einfach nur die hexadezimale Darstellung des Bytewerts sind, die man auch locker selber hinbekommen kann, ist dir bekannt, oder? Notfalls musst du halt einen Wrapper einführen, dessen ``__iter__``-Methode ein versionsübergreifendes Verhalten definiert.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mir geht es darum, das ich unter Py2 und Py3 gleichen code haben kann.
z.Z. habe habe ich mir if PY2: ausnahmen drin...

Aber Lösung könnte (von Sirius3) das sein:

Code: Alles auswählen

if PY2:
    iter_bytes = lambda data: (ord(b) for b in data)
else:
    iter_bytes = iter
von -> http://www.python-forum.de/viewtopic.ph ... 95#p267295

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten