2013-05-24 11 views
8

Ho voluto riempire una stringa con caratteri null ("\ x00"). Conosco molti modi per farlo, quindi per favore non rispondere con alternative. Quello che voglio sapere è: perché la funzione string.format() di Python non consente il riempimento con valori null?Perché il pad string.format di Python non può essere eseguito con " x00"?

Casi di test:

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

Questo dimostra che i caratteri esadecimali escape funzionano in generale.

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

Ma "\ x00" diventa uno spazio ("\ x20").

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

Anche provare un paio di altri modi per farlo.

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

Questo funziona, ma non usa spazi string.format

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

Python è chiaramente sostitutivi (chr(0x20)) invece di valori nulli (chr(0x00)).

+4

Si prega di lasciare un commento quando si downprote quindi posso migliorare questa domanda. Ho svolto le mie ricerche e sono a conoscenza di "ljust" e di altri modi per svolgere il compito. Voglio sapere perché python 2.7 si comporta in questo modo. – bonsaiviking

+0

Usa 'stampa" bbb "+" \ x00 "* 7' e otterrai una stringa con 7 spazi. Shell stampa sempre "\ x00" come carattere di spazio. Senza print shell restituisce la versione 'repr' della stringa. –

risposta

0

Poiché il metodo string.format in Python2.7 è una porta posteriore da Python3 string.format. Python2.7 unicode è la stringa Python 3, dove la stringa Python2.7 è il byte Python3. Una stringa è il tipo sbagliato per esprimere dati binari in Python3. Dovresti usare byte che non hanno alcun metodo di formattazione. Quindi in realtà dovresti chiederti perché il metodo format su string è del tutto in 2.7 quando avrebbe dovuto essere realmente solo sul tipo unicode poiché quello è diventato la stringa in Python3.

Quale credo che la risposta sia che è troppo comodo averlo lì.

È un dato correlato perché non v'è ancora format on bytes

+0

Questo produce lo stesso risultato: "u" {0: \ x00 <10} ". Format (u" bbb ")'. Il codice sorgente mostra che i tipi unicode e string usano lo stesso formattatore. – bonsaiviking

+0

@bonsaiviking yes, il punto è che '.format' non è per dati binari e non dovrebbe essere usato per dati binari. Cercare di utilizzare il metodo unicode per i dati binari non funzionerà correttamente. – cmd

4

Scavando nel codice sorgente per Python 2.7, ho trovato che il problema è in questa sezione da ./Objects/stringlib/formatter.h, le linee 718-722 (nella versione 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); 

Il problema è che un/carattere zero nullo ('\0') viene utilizzato come un predefinito quando viene specificato alcun carattere di riempimento. Questo è quello di attivare questo comportamento:

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

può essere possibile impostare format->fill_char = ' '; come predefinito in parse_internal_render_format_spec() a ./Objects/stringlib/formatter.h:186, ma c'è un po 'di compatibilità all'indietro che verifica la presenza '\0' in seguito. In ogni caso, la mia curiosità è soddisfatta. Accetterò la risposta di qualcun altro se ha più storia o una spiegazione migliore del perché di questo.

2

La risposta alla domanda originale è che si trattava di un bug in Python.

È stato documentato come consentito, ma non lo era. È stato corretto nel 2014. Per python 2, la correzione è apparsa per la prima volta in 2.7.7 o 2.7.8 (non so come dire quale)

Originale tracciato issue.

Problemi correlati