2015-04-19 11 views
6

Sto provando a scrivere il simbolo in un file di testo in python. Penso che abbia qualcosa a che fare con la codifica (utf-8). Ecco il codice:Come stampare simboli come ● nei file in Python

# -*- coding: utf-8 -*- 
outFile = open('./myFile.txt', 'wb') 
outFile.write("●") 
outFile.close() 

Invece del nero "●" ottengo "â—". Come posso risolvere questo?

+2

Grazie per le vostre risposte! Ho scoperto che il problema era che Wordpad non mostrava il punto, ma il blocco note lo ha fatto. Quindi in realtà ha funzionato sin dall'inizio. –

+0

Python 2 o 3? (Suggerimento: Py3 è migliore) – JeromeJ

+0

Ancora, ci sono problemi con il codice qui sopra: fondamentalmente funziona solo se (1) il tuo editor di programma usa effettivamente UTF-8 (questo potrebbe non essere stato il caso) e (2) con il testo visualizzatori di file che utilizzano la stessa codifica del * tuo * editor di programmazione. Puoi dare un'occhiata alla mia soluzione, a qualcosa che dovrebbe dare "●" su quasi tutte le macchine, per quasi tutti gli utenti, qualunque sia la loro codifica di scelta. – EOL

risposta

1

Se si sta utilizzando Python 2, utilizzare codecs.open invece di open e unicode invece di str:

# -*- coding: utf-8 -*- 
import codecs 
outFile = codecs.open('./myFile.txt', 'wb', 'utf-8') 
outFile.write(u"●") 
outFile.close() 

In Python 3, passare l'argomento encoding parola chiave per open:

# -*- coding: utf-8 -*- 
outFile = open('./myFile.txt', 'w', encoding='utf-8') 
outFile.write("●") 
outFile.close() 
+0

Hai ragione, ma il codice originale scrive esattamente lo stesso file ... –

3

Aprire il file utilizzando il pacchetto io affinché funzioni sia con python2 sia con python3 con la codifica impostata su utf8 affinché funzioni. Durante la stampa, durante la scrittura, scrivi come stringa unicode.

import io 
outFile = io.open('./myFile.txt', 'w', encoding='utf8') 
outFile.write(u'●') 
outFile.close() 

provata su Python 2.7.8 e Python 3.4.2

+1

Questo è solo per Python 3, e funziona solo se l'output desiderato è UTF-8 (non deve essere la stessa codifica di quella usata da l'editor di programmi, e generalmente varia da macchina a macchina, specialmente nel mondo Windows e in alcuni paesi). – EOL

+0

@EOL, Esatto. Ho aggiornato la mia risposta per rimediare alla mancanza della mia vecchia risposta. Grazie :) –

+0

Se devi usarlo su un sistema compatibile con UTF-8, non aggiungi molto al codice originale che scrive esattamente lo stesso file! –

0
>>> ec = u'\u25cf' # unicode("●", "UTF-8") 
>>> open("/tmp/file.txt", "w").write(ec.encode('UTF-8')) 
0

Che cosa il vostro programma non è quello di produrre un file di output nella stessa codifica come editor di programma di (la coding in alto non importa, a meno che l'editor del programma lo usa per salvare il file). Pertanto, se apri myFile.txt con un programma che utilizza la stessa codifica dell'editor di programma, tutto sembra a posto.

Ciò non significa che il programma funzioni per tutti.

Per questo, è necessario fare due cose. È necessario prima indicare la codifica utilizzata per i file di testo sulla macchina. Questo è un po 'difficile da individuare, ma il seguente dovrebbe spesso funzionare:

# coding=utf-8 # Put your editor's encoding here 

import codecs 
import locale 
import sys 

# Selection of the first non-None, reasonable encoding: 
out_encoding = (locale.getlocale()[1] 
       or locale.getpreferredencoding() 
       or sys.stdin.encoding or sys.stdout.encoding 
       # Default: 
       or "UTF8") 

outFile = codecs.open('./myFile.txt', 'w', out_encoding) 

Nota che è molto importante specificare destra coding sulla parte superiore del file: questo deve essere la codifica l' editor diprogramma .

Se si conosce la codifica desiderata per il file di output, è possibile inserirla direttamente in open(). Altrimenti, l'espressione più generica e portatile out_encoding dovrebbe funzionare per la maggior parte degli utenti sulla maggior parte dei computer (ad esempio, qualunque sia la loro codifica di scelta, dovrebbero essere in grado di leggere "●" nel file risultante, assumendo che la codifica del computer possa rappresentarlo) .

allora si deve stampare una stringa, non byte:

outFile.write(u"●") 

(notare il leader u, che significa "stringa unicode").

Per una comprensione più approfondita dei problemi in questione, una delle mie risposte precedenti dovrebbe essere molto utile: UnicodeDecodeError when redirecting to file.

+0

La tua soluzione è davvero bella ... sfortunatamente il proiettile non ha rappresentazione in ISO-8859-1! (o non riuscivo a trovarlo :-() –

+0

Infatti, questo proiettile non esiste in Latin 1, né "•". – EOL

0

Questo dovrebbe fare il trucco

# -*- coding: utf-8 -*- 
outFile = open('./myFile.txt', 'wb') 
outFile.write(u"\u25CF".encode('utf-8')) 
outFile.close() 

uno sguardo al this

0

Mi dispiace molto, ma scrivere un simbolo in un file di testo senza dire ciò che la codifica del file dovrebbe essere è semplicemente non senso.

Potrebbe non essere evidente a prima vista, ma i file di testo sono infatti codificati e possono essere codificati in modi diversi. Se hai solo lettere (maiuscole e minuscole, ma non accentate), cifre e simboli semplici (tutto ciò che ha un codice ASCII sotto 128), tutto dovrebbe andare bene, perché i 7 bit ASCII sono ormai uno standard e in effetti quei caratteri hanno la stessa rappresentazione nelle principali codifiche.

Ma non appena si ottengono simboli veri o caratteri accentati, la loro rappresentazione varia da una codifica all'altra. Ad esempio, il simbolo ● ha una rappresentazione UTF-8 di (codifica Python): \xe2\x97\x8f. Ciò che è peggio, non può essere rappresentato nella codifica latin1 (ISO-8859-1).

Un altro esempio è il francese e accento aigu: é è rappresentato in UTF-8 come \xc3\xa9 (nota 2 byte), ma è rappresentato in Latin1 come \x89 (un singolo byte)

Così ho provato il codice nella mia casella Ubuntu utilizzando una codifica UTF8 e il comando cat myFile.txt ... ha mostrato correttamente il proiettile!

[email protected]:~/stackoverflow$ cat myFile.txt 
●[email protected]:~/stackoverflow$ 

(come non è stato aggiunto alcun ritorno a capo dopo il proiettile, il prompt segue immediatamente esso)

In conclusione:

Il codice scrive correttamente il proiettile al file nella codifica UTF8. Se il tuo sistema usa nativamente un'altra codifica (ISO-8859-1 o la sua variante Windows-1252) non puoi convertirlo nativamente perché questo personaggio semplicemente non esiste in questa codifica.

Ma è sempre possibile vederlo in un editor di testo che supporta codifica diversa come l'eccellente vim esistente su tutti i principali sistemi.


Prova di sopra:

Su un computer Windows 7, ho aperto una finestra di vim e istruito ad accettare utf8 con :set encoding='utf8'. Ho quindi incollato il codice originale da OP e l'ho salvato in un file foo.py.

ho aperto una finestra cmd.exe ed eseguito python foo.py (utilizzando un Python 2.7): ha creato un file myFile.txt contenente i 3 byte (esa): e2 97 8fche è la rappresentazione utf8 del proiettile (ho potuto confermare con vim Tools/Hexa convert).

Potrei anche aprire myFile.txt inattivo e in realtà ho visto il proiettile. Anche notepad.exe potrebbe mostrare il proiettile!

Quindi, anche su un computer Windows 7 che non nativamente accetta utf-8, il codice OP genera correttamente un file di testo che quando aperto con un editor di testo che accetta UTF-8 contiene il proiettile .

Naturalmente, se si tenta di aprire myFile.txt con vim in modalità latin1, ottengo: â—, su una finestra CMD con tabella codici 850, type myFile.txt mostra ÔùÅ, e con tabella codici 1252 (variante latin1): A-.

In conclusione, il codice OP crea un file codificato utf8 corretto: spetta alla parte di lettura interpretare correttamente utf8.

+0

ASCII ha 128 caratteri, non 127, quindi ho aggiornato la tua risposta – EOL

+0

Ho anche corretto quello che Dite sulla "rappresentazione unicode", che è qualcosa che non esiste: in realtà stavate citando la rappresentazione UTF-8 (che non è l'unica codifica in Unicode) – EOL

+0

Infine, non è esattamente vero che il codice "scrive correttamente" nella codifica UTF8 ": funziona solo se l'editor di programma utilizzato utilizza effettivamente UTF8 (che è sempre lontano dal caso, specialmente su Windows). Il fatto generale del codice nella domanda è che il suo file di output è nello stesso codifica come editor di programmi (il 'coding' in alto non ha importanza) – EOL