Ik gebruik een recent Linux-systeem waarbij al mijn landinstellingen UTF-8 zijn:
LANG=de_DE.UTF-8
LANGUAGE=
LC_CTYPE="de_DE.UTF-8"
LC_NUMERIC="de_DE.UTF-8"
LC_TIME="de_DE.UTF-8"
...
LC_IDENTIFICATION="de_DE.UTF-8"
LC_ALL=
Nu wil ik UTF-8-gecodeerde inhoud naar de console schrijven.
Op dit moment gebruikt Python UTF-8 voor de FS-codering, maar houdt het bij ASCII voor de standaardcodering 🙁
>>> import sys
>>> sys.getdefaultencoding()
'ascii'
>>> sys.getfilesystemencoding()
'UTF-8'
Ik dacht dat de beste (schone) manier om dit te doen het instellen van de omgevingsvariabele PYTHONIOENCODING
was. Maar het lijkt erop dat Python het negeert. Op mijn systeem krijg ik tenminste steeds ascii
als standaardcodering, zelfs na het instellen van de envvar.
# tried this in ~/.bashrc and ~/.profile (also sourced them)
# and on the commandline before running python
export PYTHONIOENCODING=UTF-8
Als ik het volgende doe aan het begin van een script, werkt het wel:
>>> import sys
>>> reload(sys) # to enable `setdefaultencoding` again
<module 'sys' (built-in)>
>>> sys.setdefaultencoding("UTF-8")
>>> sys.getdefaultencoding()
'UTF-8'
Maar die benadering lijkt onrein. Dus, wat is een goede manier om dit te bereiken?
Tussenoplossing
In plaats van de standaardcodering te wijzigen – wat geen goed ideeis (zie het antwoord van mesilliac) – omwikkel ik gewoon sys.stdout
met een StreamWriter
als volgt:
sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout)
Zie deze kernvoor een kleine hulpprogramma-functie die het afhandelt.
Antwoord 1, autoriteit 100%
Het lijkt erop dat dit niet wordt aanbevolen.
Fedora stelde voor de systeemlandinstelling als standaard te gebruiken,
maar blijkbaar breekt dit andere dingen.
Hier is een citaat uit de mailinglijstdiscussie:
De enige ondersteunde standaardcoderingen in Python zijn: Python 2.x: ASCII Python 3.x: UTF-8 Als je deze verandert, sta je er alleen voor en zullen er vreemde dingen gebeuren beginnen te gebeuren. De standaardcodering heeft niet alleen invloed op: de vertaling tussen Python en de buitenwereld, maar ook alle interne conversies tussen 8-bit strings en Unicode. Hacks zoals wat er gebeurt in de pango-module (instellen van de standaardcodering naar 'utf-8' door de sitemodule opnieuw te laden in om de sys.setdefaultencoding() API terug te krijgen) zijn gewoon ronduit verkeerd en zal ernstige problemen veroorzaken sinds Unicode objecten cachen hun standaard gecodeerde weergave. Schakel het gebruik van een op landinstellingen gebaseerde standaardcodering niet in. Als je alleen maar de coderingen wilt krijgen van stdout en stdin correct zijn ingesteld voor leidingen, zou u moeten doen verander in plaats daarvan het .encoding-kenmerk van die (alleen). -- Marc-André Lemburg eGenix.com
Antwoord 2, autoriteit 83%
Dit is hoe ik het doe:
#!/usr/bin/python2.7 -S
import sys
sys.setdefaultencoding("utf-8")
import site
Let op de -S
in de bangline. Dat vertelt Python de module site
niet automatisch te importeren. De module site
is wat de standaardcodering instelt en de methode verwijdert, zodat deze niet opnieuw kan worden ingesteld. Maar zal eren wat al is ingesteld.
Antwoord 3, autoriteit 34%
Hoe UTF-8-gecodeerde tekst naar de console in Python < 3?
print u"some unicode text \N{EURO SIGN}"
print b"some utf-8 encoded bytestring \xe2\x82\xac".decode('utf-8')
d.w.z. als u een Unicode-tekenreeks heeft, drukt u deze rechtstreeks af. Als je hebt
een bytestring en converteer deze dan eerst naar Unicode.
Uw landinstellingen (LANG
, LC_CTYPE
) geven een utf-8 landinstelling aan en
daarom zou je (in theorie) een utf-8 bytestring rechtstreeks kunnen afdrukken en het
moet correct worden weergegeven in uw terminal (als terminalinstellingen)
consistent zijn met de landinstellingen en dat zouden ze ook moeten zijn), maar jij
zou het moeten vermijden: de karaktercodering van uw . niet hardcoderen
omgeving in uw script; in plaats daarvan Unicode rechtstreeks afdrukken.
Er zijn veel verkeerde aannames in uw vraag.
U hoeft PYTHONIOENCODING
niet in te stellen met uw landinstellingen,
om Unicode naar de terminal af te drukken. utf-8 locale ondersteunt alle Unicode-tekens, d.w.z. het werkt zoals het is.
U hebt de tijdelijke oplossing sys.stdout =
. Het kan
codecs.getwriter(locale.getpreferredencoding())(sys.stdout)
breken als een code (die u niet beheert) bytes moet afdrukken
en/of het kan breken terwijl
Unicode afdrukken naar Windows-console (verkeerde codepagina, kan niet-decodeerbare tekens afdrukken). Correcte landinstellingen en/of PYTHONIOENCODING
envvar zijn voldoende. Als u sys.stdout
moet vervangen, dan gebruik io.TextIOWrapper()
in plaats van codecs
modulezoals win-unicode-console
pakketdoet.
sys.getdefaultencoding()
is niet gerelateerd aan uw landinstellingen en aan
PYTHONIOENCODING
. Uw veronderstelling dat het instellen van PYTHONIOENCODING
moet veranderen sys.getdefaultencoding()
is onjuist. Je zou moeten
controleer in plaats daarvan sys.stdout.encoding
.
sys.getdefaultencoding()
wordt niet gebruikt wanneer u afdrukt naar de
troosten. Het kan worden gebruikt als een fallback op Python 2 als stdout is
omgeleid naar een bestand/pipe tenzij PYTHOHIOENCODING
is ingesteld:
$ python2 -c'import sys; print(sys.stdout.encoding)'
UTF-8
$ python2 -c'import sys; print(sys.stdout.encoding)' | cat
None
$ PYTHONIOENCODING=utf8 python2 -c'import sys; print(sys.stdout.encoding)' | cat
utf8
Bel sys.setdefaultencoding("UTF-8")
niet aan; het kan je beschadigen
gegevens stilen/of breken modules van derden die niet verwachten
het. Onthoud dat sys.getdefaultencoding()
wordt gebruikt om bytestringen te converteren
(str
) van/naar unicode
in Python 2 implicietbijv. "a" + u"b"
. Zie ook,
het citaat in het antwoord van @mesilliac.
Antwoord 4, autoriteit 17%
Als het programma niet de juiste tekens op het scherm weergeeft,
d.w.z. ongeldig symbool,
voer het programma uit met de volgende opdrachtregel:
PYTHONIOENCODING=utf8 python3 yourprogram.py
Of het volgende, als uw programma een wereldwijd geïnstalleerde module is:
PYTHONIOENCODING=utf8 yourprogram
Op sommige platforms zoals Cygwin (mintty.exe
terminal) met Anaconda Python
(of Python 3
), voer je gewoon export PYTHONIOENCODING=utf8
en
later uitvoeren werkt het programma niet,
en je moet altijd elke keer PYTHONIOENCODING=utf8 yourprogram
doen om het programma correct uit te voeren.
In Linux, in het geval van sudo
, kun je proberen het argument -E
door te geven om de gebruikersvariabelen naar het sudo-proces te exporteren:
export PYTHONIOENCODING=utf8
sudo -E python yourprogram.py
Als je dit probeert en het heeft niet gewerkt, moet je een sudo-shell invoeren:
sudo /bin/bash
PYTHONIOENCODING=utf8 yourprogram
Gerelateerd:
- Afdrukken UTF-8-gecodeerde tekst naar de console in Python < 3?
- Standaardcodering van Python wijzigen?
- UTF-8 forceren via cp1252 (Python3)
- Python-pad permanent instellen voor Anaconda binnen Cygwin
- https://superuser.com/questions/1374339/what -doet-de-e-in-sudo-e-do
- Waarom bash -c ‘var= 5 printf “$var”‘ drukt geen 5 af?
- https://unix.stackexchange.com/questions/296838 /wat-het-verschil-tussen-eval-en-exec
Antwoord 5, autoriteit 10%
Terwijl we ons realiseren dat de OP-vraag voor Linux is: als je hier via een zoekmachine terechtkomt, lost het volgende het probleem op in Windows 10:
set PYTHONIOENCODING=utf8
python myscript.py