Kirjautuminen

Haku

Tehtävät

Opasarkisto: Python 2 -ohjelmointi: Liite 2 - Python ja ääkköset

  1. Osa 1 - Ensimmäinen ohjelma
  2. Osa 2 - Tiedon käsittely
  3. Osa 3 - Ehtorakenteet
  4. Osa 4 - Toistorakenteet
  5. Osa 5 - Listojen käsittely
  6. Osa 6 - Merkkijonot
  7. Osa 7 - Omat funktiot
  8. Osa 8 - Tiedostot ja virheet
  9. Osa 9 - Standardikirjasto
  10. Osa 10 - Tietorakenteet
  11. Osa 11 - Alkeita edemmäs
  12. Osa 12 - Yhteenveto
  13. Liite 1 - Asennus ja käyttö
  14. Liite 2 - Python ja ääkköset

Kirjoittaja: Metabolix (2009).

⚠ Huomio! Tämä opas on vanhentunut. Oppaan sisältöön ei voi enää luottaa. Opas on säilytetty vain sen historiallisen arvon vuoksi. ⚠


Eri tilanteissa ja eri tietokoneilla käytetään eri tapoja merkkien ilmaisemiseen. Esimerkkipaketissa on kolme samanlaista ohjelmaa (str_*.py), joista yksi on tallennettu cp1252-merkistössä, toinen cp850-merkistössä ja kolmas Unicode-merkistössä UTF-8-enkoodattuna. Mikä ohjelmista toimii sinun koneellasi – vai toimiiko mikään? Suomessa Windowsin komentorivillä toimii yleensä cp850-versio ja graafisessa IDLEssä cp1252-versio. Linux ja Mac OS X kelpuuttavat todennäköisimmin UTF-8-version, ja vanhemmissa Maceissa ei ehkä toimi näistä mikään. Väärän version käyttäminen tulostaa vääriä merkkejä.

Samassa paketissa on ohjelmista versiot, joissa tavallisen tekstien sijaan on käytetty Pythonin Unicode-tekstejä. Näistä kolmesta jokaisen pitäisi toimia täsmälleen samalla tavalla.

Tämä opas käsittelee ASCII-merkistön ulkopuolisten merkkien (mm. "ääkkösten") toimintaa Pythonissa. Ensiksi perehdytään hieman merkistökysymykseen yleisesti. Sen jälkeen vilkaistaan yleisimpiä merkistöjä, ja lopulta päästään itse asiaan, ongelmien välttämiseen Pythonissa.

Opas on kirjoitettu Python 2:n näkökulmasta. Python 3:ssa Unicode-tuki on paljon parempi, joten osa tämän oppaan asioista joko ei päde tai ei ole tarpeen Python 3:n kohdalla. Jäljempänä on pieni kommentti Python 3:sta.

Mitä ovat merkistöt?

Tietokone käsittelee kaikkea tietoa lukuina. Merkistö on sopimus siitä, mitkä lukuarvot vastaavat mitäkin graafisia merkkejä. Yksi vanha ja laajalle levinnyt merkistö on 7-bittinen ASCII-merkistö (American Standard Code for Information Interchange). Siinä määritellään lukuarvoille 0–127 tietyt merkitykset: merkistöön kuuluvat kirjaimet A–Z ja a–z, numerot 0–9, joitakin välimerkkejä ja symboleja sekä jonkin verran ohjausmerkkejä kuten rivinvaihtomerkki ja sarkain. ASCII-merkistö ei riitä kaikkeen: siitä puuttuvat mm. aksentilliset ja skandinaaviset merkit (é, ç, åäö), kyrilliset ja kreikkalaiset aakkoset sekä suuri määrä muita merkkejä kuten kiinan, japanin ja korean kirjoitusmerkit.

Nykyaikaisissa tietokoneissa muistin perusyksikkö tavu sisältää kahdeksan bittiä, sillä on siis 256 mahdollista arvoa. Koska ASCII-merkistö käsittää vain 128 eri arvoa, loput 128 voidaan käyttää muita, ASCII-merkistöstä puuttuvia merkkejä varten. Windowsin cp1252-merkistössä koodit 128–255 sisältävät yleisiä eurooppalaisia merkkejä (mm. éèçüåäö); esimerkiksi merkkiä Ä vastaa luku 196. Sen sijaan DOSin ja Windowsin komentorivin cp850-merkistössä Ä-kirjaimen koodi onkin 142. Eri maissa käytetään erilaisia merkistöjä, joista monissa ei ole ääkkösiä lainkaan: venäjänkielisen Windowsin merkistössä ASCII-merkkien jälkeen tuleekin kyrillisiä merkkejä, ja kreikankielisessä tärkeitä ovat tietenkin kreikkalaiset aakkoset.

Unicode-merkistön tarkoituksena on korjata nämä ongelmat. Unicode sisältää valtaosan maailman nykyisten kielten kirjoitusmerkeistä sekä monenlaisia symboleja mm. matemaattisia lausekkeita varten. ASCII-merkkejä on 128 erilaista, kun taas Unicode-merkkejä on määritelty jo yli satatuhatta, ja luonnollisesti yhden Unicode-merkin tallentamiseen tarvitaan enemmän muistia kuin yhden ASCII-merkin tallentamiseen. Unicode-merkistölle on monta enkoodausta. UTF-32-muodossa jokainen merkki vie neljä tavua (32 bittiä, neljän ASCII- tai cp1252-merkin verran), mutta tämä on tuhlailevaa. Yleisemmin käytössä on UTF-8-enkoodaus, jossa koodit 0–127 (ASCII-merkit) vievät yhden tavun, koodit 128–2047 vievät kaksi tavua, koodit 2048–65535 vievät kolme tavua ja koodit 65536–1114111 vievät neljä tavua. Tällä tavalla yleisimmät merkit mahtuvat pienempään tilaan kuin harvinaisemmat. Pelkkiä ASCII-merkkejä sisältävä UTF-8-teksti vastaa täsmälleen tavallista ASCII-tekstiä. Sen sijaan merkki Ä, joka on Unicode-arvoltaan 196 (kuten cp1252-merkistössäkin), tallennetaan UTF-8-enkoodauksessa kahtena tavuna (195, 132). (Lisätietoja Unicode-enkoodauksista on Unicoden UTF-FAQ:ssa.)

Linuxissa on usein käytössä juuri UTF-8-enkoodattu Unicode-merkistö mutta joskus myös cp1252-merkistöä muistuttava ISO-8859-1-merkistö tai ISO-8859-15-merkistö, joista kerrotaan hieman seuraavassa kappaleessa.

Yleisiä merkistöjä

Tässä on muutaman yleisen merkistön merkkejä järjestyksessä. Symboli tarkoittaa, että kyseinen koodi ei ole käytössä. Kaikki merkit eivät välttämättä näy oikein, joten listauksiin kannattaa suhtautua varoen.

ASCII-merkistön alussa on joitakin erikoismerkkejä kuten rivinvaihtomerkki, ja viimeinen koodi (127) tarkoittaa deleteä. Koodista 32 alkavat varsinaiset graafiset merkit, ensimmäisenä välilyönti:

 !"#$%&'()*+,-./0123456789:;<=>?
@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
`abcdefghijklmnopqrstuvwxyz{|}~

(Wikipediassa on lisätietoja ASCII-merkistön historiasta ja käytöstä.)

DOSissa käytettiin länsieurooppalaisille aakkosille usein cp850-merkistöä, ja se on yhä käytössä Windowsin komentorivillä. Se sisältää ASCII-merkkien lisäksi ääkkösiä ja aksentillisia kirjaimia sekä joitain erityisiä graafisia merkkejä, joita on DOSissa käytetty esimerkiksi ikkunoiden piirtämiseen.

ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃
áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐
└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈıÍÎÏ┘┌█▄¦Ì▀
ÓßÔÒõÕµþÞÚÛÙýݯ´-±‗¾¶§÷¸°¨·¹³²■ 

(Wikipediassa on täysi merkkitaulukko sekä lisätietoja englanniksi.)

Länsi-Euroopassa Windowsissa yleisesti käytettävässä Windows-1252- eli cp1252-merkistössä on enemmän kirjainmerkkejä, ja järjestyskin on hieman vaihtunut. Alku on taas sama kuin ASCII-merkistössä.

€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ
 ¡¢£¤¥¦§¨©ª«¬-®¯°±²³´µ¶·¸¹º»¼½¾¿
ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß
àáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ

(Wikipediassa on täysi merkkitaulukko sekä lisätietoja englanniksi.)

Hyvin yleisesti käytössä on myös hieman vanhempi ISO-8859-1, toiselta nimeltään latin-1. Se vastaa muuten cp1252-merkistöä, mutta koodit 128–159 (ensimmäiset 32 koodia ASCII-alueen jälkeen, edellisen taulukon ylin rivi) on varattu erityistarkoituksiin. Tästä merkistöstä on myöhemmin kehitetty ISO-8859-15, jossa on poistettu muutama harvemmin tarpeellinen merkki (¤¦¨´¸¼½¾) ja lisätty tilalle joitakin puuttuvia (€ŠšŽžŒœŸ). (Wikipediassa on täydet ISO-8859-1- ja ISO-8859-15-merkkitaulukot sekä lisätietoja englanniksi.)

Unicode-merkistön ensimmäiset 256 koodia vastaavat ISO-8859-1-merkistöä, ja tämän jälkeen tulee suuri joukko muita merkkejä ja symboleja. Unicode-merkistö kattaa useimmat nykymaailman kirjoitusmerkit. Esimerkiksi kirjain Ä on kohdassa 196 (U+00E4), euromerkki € kohdassa 8364 (U+20AC) ja kiinalainen kirjoitusmerkki 漢 kohdassa 28450 (U+6F22). Unicode-merkit voidaan tallentaa joko suurina lukuina (UTF-32) tai hieman tiivistetyssä muodossa (mm. UTF-8), jossa yleisimmät merkit vievät vähemmän muistia kuin harvinaisemmat. (Näitä enkoodauksia käsiteltiin hieman jo edellisessä kappaleessa, ja lisätietoa on Unicoden UTF-FAQ:ssa.)

Väärän merkistön perusongelma

Pythonissa tekstit ovat vain tavujonoja. Kun lähdekoodiin kirjoitetaan 'åäö', kooditiedostoon tallentuu eri tavuja sen mukaan, mitä merkistöä tekstieditori käyttää. Python-ohjelma tulostaa juuri nämä tavut riippumatta siitä, mitä merkistöä tulostukseen pitäisi käyttää. Niinpä esimerkkikoodien (str_*.py) tulosteet riippuvat ajoympäristöstä.

#!/usr/bin/python
# -*- coding: cp1252 -*-
# Vaihda merkistön nimi sen mukaan, mitä tekstieditorisi käyttää!

import sys
print 'Tässä ohjelmassa käytetään cp1252-merkistöä.'
print 'sys.stdout.encoding =', sys.stdout.encoding
print 'len("ä") =', len("ä")

Tässä ovat cp1252-version tulosteet Windowsin komentorivillä, graafisessa Python-ympäristössä sekä Linuxissa.

Windows, graafinen Python-ympäristö (IDLE) kirjoitti:

Tässä ohjelmassa käytetään cp1252-merkistöä.
sys.stdout.encoding = cp1252
len("ä") = 1

Windows, komentorivi kirjoitti:

Tõssõ ohjelmassa kõytetõõn cp1252-merkist÷õ.
sys.stdout.encoding = cp850
len("õ") = 1

Linux kirjoitti:

T�ss� ohjelmassa k�ytet��n cp1252-merkist��.
sys.stdout.encoding = UTF-8
len("�") = 1

Eri versioiden viimeinen rivi tuottaa eri järjestelmissä erilaisia tuloksia:

Järjestelmäcp850-versiocp1252-versioUTF-8-versio
Windows, komentorivilen("ä") = 1len("õ") = 1len("├ñ") = 2
Windows, IDLElen("„") = 1len("ä") = 1len("ä") = 2
Linux (UTF-8)len("�") = 1len("�") = 1len("ä") = 2

UTF-8-version tulosteista nähdään, että len-funktio ilmoittaa ä-kirjaimen pituudeksi kaksi merkkiä, koska se UTF-8-enkoodattuna vie kaksi tavua muistia. Samasta syystä esimerkiksi sanan 'ääliö' pituudeksi ilmoitetaan peräti kahdeksan merkkiä!

Unicode-tekstit

Pelkkä Python-koodin alussa oleva merkistöilmoitus ei saa ohjelmaa toimimaan muita merkistöjä käyttävissä ympäristöissä. Jotta ohjelma toimisi, pitää käyttää tavallisten tekstien sijaan erityisiä Unicode-tekstejä. Python-tulkki näkee tiedoston alussa, mitä merkistöä lähdekoodi käyttää, ja kun koodissa tulee vastaan Unicode-teksti, Python-tulkki muuttaa kaikki merkit vastaaviksi Unicode-merkeiksi. Unicode-teksti taas muutetaan tulostusvaiheessa järjestelmälle sopivaan merkistöön.

Unicode-tekstin tunnistaa siitä, että ennen ensimmäistä lainaus- tai heittomerkkiä on u-kirjain.

s = 'moi'  # tavallista tekstiä
u = u'moi' # Unicode-tekstiä

Unicode-tekstit toimivat aivan kuten tavallisetkin tekstit: niitä voi yhdistellä, muuttaa luvuiksi jne. Muiden tyyppien muunnos Unicode-tekstiksi täytyy tehdä funktiolla unicode.

teksti = u'123'
luku = int(teksti)
print luku, u'* 3 =', luku * 3
teksti = unicode(luku * 3)
print u'Onko', len('ä'), u'sama kuin', len(u'ä'), u'?'

Aiempaa vastaava esimerkkiohjelma Unicode-teksteillä näyttää siis tältä:

#!/usr/bin/python
# -*- coding: cp1252 -*-
# Vaihda merkistön nimi sen mukaan, mitä tekstieditorisi käyttää!

import sys
print u'Tässä ohjelmassa käytetään cp1252-merkistöä.'
print u'Tekstit ovat Unicode-tekstejä ja toimivat siksi paremmin.'
print u'sys.stdout.encoding =', sys.stdout.encoding
print u'len("ä") =', len("ä")
print u'len(u"ä") =', len(u"ä")

Esimerkkipaketin tiedostoissa unicode_*.py on tämä esimerkki eri enkoodauksilla.

Helppoa! Vai onko sittenkään?

Oikean merkistöilmoituksen selvittäminen

Jotta Unicode-tekstit toimisivat, merkistöilmoituksen täytyy vastata kooditiedoston eli käytännössä tekstieditorin todellista merkistöä. Joissain editoreissa käytettävän merkistön voi valita joko tallentamisen yhteydessä tai muualta valikoista, ja esimerkiksi Windowsissa IDLE tallentaa tiedoston sen mukaan, minkä merkistöilmoituksen tiedoston alkuun kirjoittaa.

Jos merkistöä ei voi valita, hyvä arvaus on Windowsissa cp1252 ja Linuxissa ja Mac OS X:ssä joko UTF-8 tai ISO-8859-1. Arvauksen onnistumisen voi selvittää ohjelmalla, jossa on Unicode-tekstinä erikoismerkkejä. Jos merkistö on testattavien merkkien osalta oikea, ohjelma tulostaa oikeat merkit. Jos merkistö on väärä, ohjelma tulostaa vääriä merkkejä. (Jos ohjelma ei toimi lainkaan, merkistö on aivan erityisen väärä.) Yksi mahdollinen testiohjelma on tällainen:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
# Vaihda ylemmälle riville oma arvauksesi!

print u'Ääkköset ja öökköset...'
# Voit testata tätäkin:
# print u'Euromerkki: €'

Puuttuvat merkit

Kaikki merkistöt eivät sisällä kaikkia merkkejä – Unicode-merkistön sadastatuhannesta merkistä vain 256 sisältyy perinteisiin merkistöihin (cp850, cp1252, ISO-8859-1). Esimerkiksi euromerkki € on cp1252-merkistössä mutta puuttuu ISO-8859-1:stä ja cp850:stä. Jos euromerkin yrittää tulostaa ympäristössä, jossa merkistö ei tue sitä, aiheutuu virhe ja ohjelman suoritus loppuu kesken. (Esimerkkipaketin tulostus_virhe.py tulostaa euromerkin; Windowsin komentorivillä tästä aiheutuu UnicodeEncodeError.)

Jotta ohjelman suoritus ei päättyisi erikoisiin merkkeihin, tekstin tulostuksen yhteydessä täytyy itse muuntaa teksti oikeaan merkistöön niin, että ongelmalliset merkit muunnetaankin kysymysmerkeiksi. Tämän voi tehdä joko joka tulostuksen yhteydessä erikseen tai helpommin niin, että muunnos tapahtuu automaattisesti. (Automaattisen muunnoksen heikkous on, että jos jostain syystä halutaan ehdottomasti tulostaa tavuja, jotka eivät sovi järjestelmän merkistöön, tulostus ei tuota toivottua tulosta. Tämä tilanne on kuitenkin harvinainen, joten automaattinen muunnos on usein käytännöllisempi.)

Järjestelmän enkoodauksen saa yleensä selville sys-moduulin olioista stdin ja stdout. Pythonin tuen tälle enkoodaukselle voi tarkistaa codecs-moduulin lookup-funktiolla. Olennaiset asiat käyvät ilmi seuraavasta esimerkistä.

#!/usr/bin/python
# -*- coding: ascii -*-

# Tarvitaan pari moduulia.
import codecs
import sys

# Funktio virran enkoodauksen selvitykseen:
def codec(f):
	try:
		# Koetetaan hakea ja tunnistaa enkoodaus.
		return codecs.lookup(f.encoding)
	except:
		# Virhetilanteessa arvataan 'latin-1'.
		return codecs.lookup('latin-1')

print u'Euromerkin Unicode-koodi on 8364 eli heksamuodossa 20ac.'
print u'Tulostetaan euromerkki:',

###########
#  TAPA 1
###########

# Haetaan tulostusta varten enkoodaus:
OUTPUT_CODEC = codec(sys.stdout)

# Enkoodataan euromerkki erikseen. Kun toisena parametrina on 'replace',
# ongelmalliset merkit vaihdetaan kysymysmerkeiksi.
print u'\u20ac'.encode(OUTPUT_CODEC.name, 'replace')

###########
#  TAPA 2
###########

# Haetaan tulostusvirran enkoodaus ja luodaan uusi virta,
# jossa ongelmamerkit vaihdetaan automaattisesti ?:ksi.
# HUOMIO! Jos teksti ei ole kokonaan ASCIIta, sen on oltava Unicode-teksti!
# Kaikki (tulostettavat) tekstit siis on parasta muuttaa Unicode-teksteiksi!
sys.stdout = codec(sys.stdout).streamwriter(sys.stdout, 'replace')

# Enkoodataan euromerkki erikseen. Kun toisena parametrina on 'replace',
# ongelmalliset merkit vaihdetaan kysymysmerkeiksi.
print u'\u20ac'

Vastaavat koodit ovat esimerkkipaketin tiedostoissa tulostus_ok.py ja tulostus_auto.py.

Syötteen lukeminen

Ohjelmalle syötettävään tekstiin pätee valitettavasti sama kuin ohjelman tulosteeseen: raw_input palauttaa merkit ajoympäristön käyttämässä merkistössä. Kun tavallista tekstiä yritetään muuttaa Unicode-tekstiksi, oletetaan, että se sisältää vain ASCII-merkkejä. Ääkkösten muuntaminen ei siis onnistu, jos lähdemerkistöä ei erikseen ilmoiteta. Tämän voi todeta syöttämällä esimerkkipaketin ohjelmalle syote_virhe.py ääkkösiä.

Jotta syötteen lukeminen onnistuisi ääkkösistä huolimatta, raw_input-funktio täytyy korvata omalla funktiolla, joka hallitsee Unicode-tekstit. Sekä kysymyksen tulostus että syötteen luku täytyy korjata, tosin jos tulostus korjataan aiemmin esitetyllä automaattisella tavalla, korjaus pätee myös raw_input-funktion kysymykseen.

#!/usr/bin/python
# -*- coding: ascii -*-

import codecs
import sys

# Funktio virran enkoodauksen selvitykseen:
def codec(f):
	try:
		# Koetetaan hakea ja tunnistaa enkoodaus.
		return codecs.lookup(f.encoding)
	except:
		# Virhetilanteessa arvataan 'latin-1'.
		return codecs.lookup('latin-1')

# Haetaan tulostusvirran enkoodaus ja luodaan uusi virta,
# jossa ongelmamerkit vaihdetaan automaattisesti ?:ksi.
# HUOMIO! Jos teksti ei ole kokonaan ASCIIta, sen on oltava Unicode-teksti!
# Kaikki (tulostettavat) tekstit siis on parasta muuttaa Unicode-teksteiksi!
sys.stdout = codec(sys.stdout).streamwriter(sys.stdout, 'replace')

# Haetaan lukuvirran enkoodaus unicode_input-funktiota varten.
INPUT_CODEC = codec(sys.stdin)

# Korvaaja raw_input-funktiolle:
def unicode_input(kysymys = u''):
	# Luetaan ja dekoodataan luettu teksti Unicode-tekstiksi.
	# Jos tulostetta ei muuteta automaattisesti, kysymys tulisi nyt
	# muuttaa erikseen kuten muutkin tulosteet:
	# OUTPUT_CODEC = codec(sys.stdout)
	# if isinstance(kysymys, unicode):
	# 	kysymys = kysymys.encode(OUTPUT_CODEC.name, 'replace')
	return raw_input(kysymys).decode(INPUT_CODEC.name, 'replace')

# Nyt tulostus onnistuu suoraan ja lukeminen unicode_input-funktiolla:
nimi = unicode_input(u'Mik\u00e4 on nimesi?\n')
print u'P\u00e4iv\u00e4\u00e4, ' + nimi + u'!'

Tämä ohjelma on esimerkkipaketin tiedostossa syote_ok.py.

Tiedon tallennus ja välitys

On tärkeää, että kun tekstejä tallennetaan tiedostoihin tai lähetetään verkossa, käytetään jotain määrättyä enkoodausta. Muunnokset Unicode-tekstin ja tietyn enkoodauksen välillä voi tehdä funktioilla encode ja decode. Kummatkin ottavat parametrikseen enkoodauksen nimen (esim. 'UTF-8') ja vapaaehtoisesti myös virheenkäsittelytapaa säätävän parametrin (esim. 'replace' tai 'strict'). Enkoodauksena UTF-8 on siitä hyvä valinta, että se pystyy esittämään kaikki Unicode-merkit eikä virheitä siis pitäisi syntyä, kunhan data on kelvollista tekstiä.

#!/usr/bin/python
# -*- coding: ascii -*-

# Lukiessa dekoodataan kaikki rivit...
rivit = []
try:
	for rivi in open('tiedosto.txt', 'r').readlines():
		rivit.append(rivi.decode('UTF-8'))
except UnicodeDecodeError as virhe:
	# Tulostetaan virheilmoitus ja lopetetaan.
	print u'Viallista dataa tiedostossa!', unicode(virhe)
	exit(1)
except IOError as virhe:
	# Tulostetaan virheilmoitus ja laitetaan testidataa.
	# Testidatan erikoismerkit on ilmoitettu nyt koodien avulla,
	# jotta esimerkki toimisi ASCII-enkoodauksellakin.
	print u'Virhe tiedoston lukemisessa!', unicode(virhe)
	print u'Otetaan testidata esiin.'
	rivit = [u'P\xe4\xe4ruoka: m\xf6ss\xf6\n', u'Hinta: 10,00 \u20ac\n']

# Tulostetaan ruudulle. Erikoismerkit muutetaan XML-merkkikoodeiksi.
for rivi in rivit:
	print rivi.encode('ascii', 'xmlcharrefreplace'),

# Kirjoittaessa enkoodataan jokainen rivi.
try:
	t = open('tiedosto.txt', 'w')
	for rivi in rivit:
		t.write(rivi.encode('UTF-8'))
except IOError as virhe:
	print u'Virhe kirjoittamisessa!', unicode(virhe)

Tämä ohjelma on esimerkkipaketin tiedostossa tiedosto.py.

Python 3

Python 3:ssa asiat ovat paljon paremmin. Kaikki teksti on oletusarvoisesti Unicode-yhteensopivaa: str-tyyppi toimii kuten Python 2:n unicode-tyyppi. Sen sijaan tietyllä tavalla tavuiksi enkoodattu teksti – kuten muukin binaaridata – täytyy tallentaa bytes-tyyppisenä. Käytännössä ero näyttää tältä:

# Python 2:
uni = u"Unicode-tekstiä!"
byt = "Tavuja."

# Python 3:
uni = "Unicode-tekstiä!"
byt = b"Tavuja."

Python 3 sisältää lukuisia muitakin uudistuksia, joiden ansiosta dataa on helpompi käsitellä Unicode-muodossa. Tarkempaa tietoa muutoksista on Python 3:n What's New -sivulla sekä varsin kattavassa Unicode-oppaassa.

Loppusanat

Merkistöt ovat ikävä ongelma. Yksi ongelman syy on, että tietokoneiden muisti, prosessointiteho ja tallennus- sekä siirtokapasiteetti ovat rajalliset, jolloin tiiviimmät merkistöt ovat nopeampia käsitellä ja säästävät tilaa. Jos muisti ja teho olisivat rajattomat, voitaisiin kaikkialla käyttää Unicode-merkistöä ilman sen kummempaa enkoodausta niin, että jokaisella merkillä olisi selkeä oma koodi. Nyt monessa tilanteessa käytetäänkin jo jonkinlaisia Unicode-ratkaisuja, mutta maailma on täynnä vanhoja ohjelmia ja vanhoja tiedostoja, joten siirtyminen uusiin, parempiin menetelmiin on hidasta. Toivottavasti tämä opas auttaa siinä edes hiukan.

Lauri Kenttä, 22.10.2009


Kommentit

Rasenger [21.02.2010 09:18:41]

#

Python 3:ssa kaikki on oletuksena Unicodea, joten siinä ei ole asian suhteen ongelmaa.

Metabolix [21.02.2010 13:53:47]

#

Opas on kirjoitettu Python 2:n näkökulmasta, koska muukin Antin opassarja käyttää tätä versiota. Python 3:ssa Unicode-tuki on paljon parempi, joten osa tämän oppaan asioista joko ei päde tai ei ole tarpeen Python 3:n kohdalla. Lisäsin oppaan loppuun osuuden Python 3:sta.

(Edit: Linkitkin päivitetty, kiitos huomautuksesta alla!)

Chiman [11.09.2010 19:53:11]

#

Metabolixin yllä olevan kommentin linkit eivät enää toimi. Tässä luultavasti tarkoitetut:
- Python 3:n What's New -sivulla
- Unicode-oppaassa

Kirjoita kommentti

Huomio! Kommentoi tässä ainoastaan tämän oppaan hyviä ja huonoja puolia. Älä kirjoita muita kysymyksiä tähän. Jos koodisi ei toimi tai tarvitset muuten vain apua ohjelmoinnissa, lähetä viesti keskusteluun.

Muista lukea kirjoitusohjeet.
Tietoa sivustosta