2013-05-24 4 views
8

Ich wollte eine Zeichenfolge mit Nullzeichen ("\ x00") auffüllen. Ich kenne viele Möglichkeiten, dies zu tun, also bitte nicht mit Alternativen antworten. Was ich wissen will, ist: Warum erlaubt Pythons string.format() Funktion kein Auffüllen mit Nullen?Warum kann Pythons string.format Pad nicht mit " x00"?

Testfälle:

>>> "{0:\x01<10}".format("bbb") 
'bbb\x01\x01\x01\x01\x01\x01\x01' 

Dies zeigt, dass hex-Escape-Zeichen in der Regel arbeiten.

>>> "{0:\x00<10}".format("bbb") 
'bbb  ' 

Aber "\ x00" wird in ein Leerzeichen ("\ x20") umgewandelt.

>>> "{0:{1}<10}".format("bbb","\x00") 
'bbb  ' 
>>> "{0:{1}<10}".format("bbb",chr(0)) 
'bbb  ' 

Auch versuchen ein paar andere Möglichkeiten, es zu tun.

>>> "bbb" + "\x00" * 7 
'bbb\x00\x00\x00\x00\x00\x00\x00' 

Dies funktioniert, aber nicht string.format

>>> spaces = "{0: <10}".format("bbb") 
>>> nulls = "{0:\x00<10}".format("bbb") 
>>> spaces == nulls 
True 

Python nicht verwendet wird klar ersetzen Räume (chr(0x20)) anstelle von NULL-Werte (chr(0x00)).

+4

Bitte hinterlassen Sie einen Kommentar, wenn Sie downvote, damit ich diese Frage verbessern kann. Ich habe meine Forschung getan und weiß über 'nur 'und andere Wege, die Aufgabe zu erfüllen. Ich möchte wissen, warum sich Python 2.7 so verhält. – bonsaiviking

+0

Verwenden Sie 'print' bbb" + "\ x00" * 7' und Sie erhalten eine Zeichenfolge mit 7 Leerzeichen. Shell druckt immer "\ x00" als Leerzeichen. Ohne print shell gibt die 'repr'-Version der Zeichenfolge zurück. –

Antwort

0

Da die string.format-Methode in Python2.7 ist ein Back-Port von Python3 string.format. Python2.7 Unicode ist die Python 3-Zeichenfolge, wobei die Python2.7-Zeichenfolge die Python3-Byte ist. Eine Zeichenfolge ist der falsche Typ zum Ausdrücken binärer Daten in Python3. Sie würden Bytes verwenden, die keine Formatmethode haben. Also sollten Sie wirklich fragen, warum die Methode format überhaupt in 2.7 ist, wenn es wirklich nur auf dem Unicode-Typ hätte sein sollen, da das die Zeichenfolge in Python3 wurde.

Welche ich denke, diese Antwort ist, dass es zu bequem ist, es dort zu haben.

Als relevante Frage, warum es nicht format on bytes noch

+0

Dies ergibt das gleiche Ergebnis: 'u" {0: \ x00 <10} ". Format (u" bbb ")'. Der Quellcode zeigt, dass Unicode- und String-Typen denselben Formatierer verwenden. – bonsaiviking

+0

@bonsaiviking ja, der Punkt ist, dass '.format' ist nicht für Binärdaten und sollte nicht für Binärdaten verwendet werden. Der Versuch, die Unicode-Methode für Binärdaten zu verwenden, wird nicht gut funktionieren. – cmd

4

Graben in den Quellcode für Python 2.7, fand ich, dass das Problem in diesem Abschnitt ist von ./Objects/stringlib/formatter.h, Linien 718-722 (in Version 2.7.3) :

/* Write into that space. First the padding. */ 
p = fill_padding(STRINGLIB_STR(result), len, 
       format->fill_char=='\0'?' ':format->fill_char, 
       lpad, rpad); 

Das Problem ist, dass ein Null-/Null-Zeichen ('\0') als Standard verwendet werden, wenn kein Füllzeichen angegeben ist. Das ist dieses Verhalten zu aktivieren:

>>> "{0:<10}".format("foo") 
'foo  ' 

Es kann möglich sein, format->fill_char = ' '; als Standard in parse_internal_render_format_spec() bei ./Objects/stringlib/formatter.h:186 zu setzen, aber es gibt einige wenig über die Abwärtskompatibilität, die später für '\0' prüft. Auf jeden Fall ist meine Neugier befriedigt. Ich werde die Antwort von jemand anderem akzeptieren, wenn es mehr Geschichte oder eine bessere Erklärung für warum als das hat.

2

Die Antwort auf die ursprüngliche Frage ist, dass es ein Fehler in Python war.

Es wurde dokumentiert, wie erlaubt, war es aber nicht. Es wurde im Jahr 2014 behoben. Für Python 2 erschien der Fix entweder in 2.7.7 oder 2.7.8 (ich weiß nicht, wie ich sagen soll)

Original tracked issue.

Verwandte Themen