Domanda

stavo guardando questo e ha iniziato a chiedersi che cosa fa il print effettivamente fare.

Non ho mai trovato il modo di utilizzare e string.decode() string.encode() per ottenere una stringa unicode "out" nella shell interattiva pitone nello stesso formato di stampa fa. Non importa quello che faccio, ottengo uno

  1. UnicodeEncodeError o
  2. la stringa di escape con "\ x ##" notazione ...

Questa è python 2.x, ma sto già cercando di riparare le mie vie e in realtà chiamare print():)

Esempio:

>>> import sys
>>> a = '\xAA\xBB\xCC'
>>> print(a)
ª»Ì
>>> a.encode(sys.stdout.encoding)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
UnicodeDecodeError: 'ascii' codec can't decode byte 0xaa in position 0: ordinal not in range(128)
>>> a.decode(sys.stdout.encoding)
u'\xaa\xbb\xcc'

Modifica :

Perché sto chiedendo questo? Sono malato e stanco di errori encode() e si rese conto che da quando print può farlo (almeno nella shell interattiva). So che il deve essere un modo per fare magicamente la codifica CORRETTAMENTE , scavando le informazioni che cosa codifica da utilizzare da qualche parte ...

Ulteriori informazioni : Io corro Python 2.4.3 (1 # 3 Set 2009 15:37:12) [GCC 4.1.2 20.080.704 (Red Hat 4.1.2-46)] sulla linux2

>>> sys.stdin.encoding
'ISO-8859-1'
>>> sys.stdout.encoding
'ISO-8859-1'

Tuttavia, i risultati sono gli stessi con Python 2.6.2 (r262: 71600, 8 Settembre 2009, 13:06:43) sulla stessa macchina Linux

.
È stato utile?

Soluzione

Modifica (Le principali modifiche tra questa modifica e quello precedente .... Nota: sto usando Python 2.6.4 su una casella di Ubuntu)

In primo luogo, nel mio primo tentativo di risposta, ho fornito alcune informazioni generali sul print e str che ho intenzione di lasciare sotto a beneficio di chiunque abbia problemi più semplici con print e chancing su questa domanda. Come per un nuovo tentativo di affrontare la questione vissuta dal PO ... Fondamentalmente, io sono propenso a dire che non c'è pallottola d'argento qui e se print qualche modo riesce a dare un senso a una stringa strano letterale allora questo non è il comportamento riproducibili . Sono portato a questa conclusione dal seguente interazione divertente con Python nella mia finestra del terminale:

>>> print '\xaa\xbb\xcc'
��

Hai provato a ingresso ª »Ì direttamente dal terminale? A un terminale Linux utilizzando utf-8 come codifica, questo è effettivamente letti come sei byte, che possono poi essere fatte per assomigliare tre caratteri unicode con l'aiuto del metodo decode:

>>> 'ª»Ì'
'\xc2\xaa\xc2\xbb\xc3\x8c'
>>> 'ª»Ì'.decode(sys.stdin.encoding)
u'\xaa\xbb\xcc'

Quindi, la '\xaa\xbb\xcc' letterale senso solo se si decodificarlo come un latin-1 letterale (beh, in realtà si potrebbe usare una codifica diversa che concorda con latin-1 sui personaggi importanti). Per quanto riguarda print 'solo lavorando' nel tuo caso, di certo non fa per me - come detto sopra

.

Ciò si spiega con il fatto che quando si utilizza una stringa letterale non preceduto da un u - cioè "asdf" anziché u"asdf" - la stringa risultante utilizzerà parte codifica non unicode. No; come un dato di fatto, l'oggetto stringa stessa sta per essere codifica-inconsapevoli, e si sta andando ad avere per trattarlo come se fosse codificato con codifica x, per il valore corretto di x. Questa idea di base mi porta alla seguente:

a = '\xAA\xBB\xCC'
a.decode('latin1')
# result: u'\xAA\xBB\xCC'
print(a.decode('latin1'))
# output: ª»Ì

Si noti la mancanza di errori di decodifica e l'uscita corretta (che mi aspetto di essere rimanere adeguata in qualsiasi altro contenitore). A quanto pare il tuo stringa letterale può essere fatta senso di da Python, ma non senza qualche aiuto.

Fa questo aiuto? (Almeno a capire come funzionano le cose, se non a rendere la gestione delle codifiche più facile ...)


Ora, per alcuni bit divertenti con qualche valore esplicativo (si spera)! Questo funziona bene per me:

sys.stdout.write("\xAA\xBB\xCC".decode('latin1').encode(sys.stdout.encoding))

Saltare sia la decodifica o la codifica risultati in parte un'eccezione unicode-related. Teoricamente parlando, questo ha un senso, come è necessaria la prima decodifica di decidere quali caratteri ci sono nella stringa data (l'unica cosa ovvia a prima vista è quello che bytes ci sono - il Python 3 idea di avente stringhe (unicode) per i caratteri e byte, per bene, byte, sembra improvvisamente superba ragionevole), mentre è necessaria la codifica in modo che l'uscita rispetta la codifica del flusso di uscita. Ora questo

sys.stdout.write("ąöî\n".decode(sys.stdin.encoding).encode(sys.stdout.encoding))

funziona anche come previsto, ma i caratteri sono effettivamente provengono dalla tastiera e così sono effettivamente codificati con la codifica stdin ... Inoltre,

ord('ą'.decode('utf-8').encode('latin2'))

restituisce il corretto 177 (il mio codifica ingresso è utf-8), ma '\ XC4 \ x85'.encode (' latin2 ') non ha senso a Python, in quanto non ha alcuna idea di come dare un senso' \ XC4 \ x85' e figure che cercare il 'codice ASCII' è il meglio che può fare.


La risposta originale:

Il po 'rilevante della documentazione Python (per la versione 2.6.4) dice che print(obj) è destinato a stampare la stringa data dal str(obj). Suppongo che si possa poi avvolgerla in una chiamata a unicode (come in unicode(str(obj))) per ottenere una stringa unicode fuori - o si potrebbe utilizzare Python 3 e scambiare questo particolare fastidio per un paio di quelle diverse. ; -)

Per inciso, questo dimostra che è possibile manipolare il risultato di printing un oggetto, proprio come è possibile alla manipolazionein ritardo il risultato della chiamata str su un oggetto, cioè per fare scherzi con il metodo __str__. Esempio:

class Foo(object):
    def __str__(self):
        return "I'm a Foo!"

print Foo()

Per quanto riguarda l'effettiva attuazione di print, mi aspetto che questo non sarà utile a tutti, ma se si davvero vogliono sapere cosa sta succedendo ... E 'nel file Python/bltinmodule.c in Python fonti (sto guardando la versione 2.6.4). Ricerca di una linea che inizia con builtin_print. In realtà è del tutto semplice, nessuna magia succedendo lì. : -)

Speriamo che questo risponde alla tua domanda ... Ma se avete un problema più arcana che mi manca del tutto, fare un commento, farò un secondo tentativo. Inoltre, sto assumendo abbiamo a che fare con Python 2.x; altrimenti credo che non avrei un commento utile.

Altri suggerimenti

print() utilizza sys.stdout.encoding per determinare ciò che la console di output può capire e quindi utilizza questa codifica nella chiamata a str.encode().

[EDIT] Se guarda alla fonte , diventa sys.stdout e quindi chiama:

PyFile_WriteObject(PyTuple_GetItem(args, i), file,
                 Py_PRINT_RAW);

Credo che la magia è nel Py_PRINT_RAW ma la fonte , dice solo:

    if (flags & Py_PRINT_RAW) {
    value = PyObject_Str(v);
    }

Quindi, nessuna magia qui. Un ciclo su argomenti con sys.stdout.write(str(item)) dovrebbe fare il trucco.

>>> import sys
>>> a = '\xAA\xBB\xCC'
>>> print(a)
ª»Ì

Tutti print sta facendo qui sta scrivendo grezzo bytes per sys.stdout. Il a stringa è una stringa di byte, non caratteri Unicode.

  

Perché sto chiedendo questo? Sono malato e stanco di codifica) errori (e si rese conto che da quando la stampa può farlo (almeno nella shell interattiva). So che il deve essere un modo per fare magicamente la codifica CORRETTAMENTE, scavando le informazioni che cosa codifica da utilizzare da qualche parte ...

Ahimè no, print sta facendo nulla di magico qui. Si passerà ad essa alcuni byte, fa uscire i byte su stdout.

Per usare .encode() e .decode() correttamente, è necessario comprendere la differenza tra byte e caratteri, e ho paura che c'è bisogno di capire la codifica corretta da utilizzare.

import sys

source_file_encoding = 'latin-1' # if there is no -*- coding: ... -*- line

a = '\xaa\xbb\xcc' # raw bytes that represent string in source_file_encoding

# print bytes, my terminal tries to interpret it as 'utf-8'
sys.stdout.write(a+'\n') 
# -> ��

ua = a.decode(source_file_encoding)
sys.stdout.write(ua.encode(sys.stdout.encoding)+'\n')
# -> ª»Ì

Definizione del codice sorgente Python codifiche

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top