TLDR? Provare:file = open(filename, encoding='cp437)
Perché? Quando si usa:
file = open(filename)
text = file.read()
Python presuppone che il file usi la stessa tabella codici dell'ambiente corrente (cp1252 nel caso del post di apertura) e prova a decodificarlo sul proprio UTF-8 predefinito. Se il file contiene caratteri di valori non definiti in questa tabella codici (come 0x90), otteniamo UnicodeDecodeError. A volte non conosciamo la codifica del file, a volte la codifica del file potrebbe non essere gestita da Python (come ad esempio cp790), a volte il file può contenere codifiche miste.
Se tali personaggi non sono necessari, si può decidere di sostituirli con punti interrogativi, con:
file = open(filename, errors='replace')
Un'altra soluzione alternativa è utilizzare:
file = open(filename, errors='ignore')
I personaggi vengono quindi lasciati intatti, ma verranno mascherati anche altri errori.
Una buona soluzione è quella di specificare la codifica, ma non alcuna codifica (come cp1252), ma quella che ha TUTTI i caratteri definiti (come cp437):
file = open(filename, encoding='cp437')
La tabella codici 437 è la codifica DOS originale. Tutti i codici sono definiti, quindi non ci sono errori durante la lettura del file, nessun errore viene mascherato, i caratteri vengono conservati (non del tutto lasciati intatti ma comunque distinguibili).