# Strängar (Python)

En förklaring hur du hanterar strängar i Python och GTK+.
Sebastian Pölsterl
sebp@k-d-w.org 2011
Marta Maria Casetti
mmcasetti@gmail.com 2012
Sebastian Rasmussen
sebras@gmail.com 2019
Anders Jonsson
anders.jonsson@norsjovallen.se 2021

# Strängar

GNOME rekommenderar starkt att använda Python 3 för att skriva program!

# Strängar i Python 2

Python 2 kommer med två olika sorters objekt som kan användas för att representera strängar, `str` och `unicode`. Instanser av `unicode` används för att uttrycka Unicode-strängar, medan instanser av typen `str` är byterepresentationer (den kodade strängen). Under huven representerar Python Unicode-strängar antingen som 16- eller 32-bitars heltal, beroende på hur Python-tolken kompilerades.

>>> unicode_string = u"Fu\u00dfb\u00e4lle" >>> print unicode_string Fußbälle

Unicode-strängar kan konverteras till 8-bitars strängar med `unicode.encode()`. Pythons 8-bitars strängar har en `str.decode()`-metod som tolkar strängen med given kodning (det vill säga, det är inversen av `unicode.encode()`):

>>> type(unicode_string) <type 'unicode'> >>> unicode_string.encode("utf-8") 'Fu\xc3\x9fb\xc3\xa4lle' >>> utf8_string = unicode_string.encode("utf-8") >>> type(utf8_string) <type 'str'> >>> unicode_string == utf8_string.decode("utf-8") True

Tyvärr låter Python 2.x dig mixa `unicode` och `str` om 8-bitarssträngen råkade innehålla endast 7-bitars byte (ASCII), men skulle få UnicodeDecodeError om den innehöll värden som inte var ASCII.

# Strängar i Python 3

Sedan Python 3.0 lagras alla strängar som Unicode i en instans av typen `str`. Kodade strängar representeras å andra sidan som binärdata i form av instanser av typen ”bytes”. Konceptuellt refererar `str` till text, medan ”bytes” refererar till data. Använd `encode()` för att gå från `str` till `bytes`, och `decode()` för att gå från `bytes` till `str`.

Vidare är det inte längre möjligt att mixa Unicode-strängar med kodade strängar, eftersom det kommer resultera i ett :exc:`TypeError`:

>>> text = "Fu\u00dfb\u00e4lle" >>> data = b" sind rund" >>> text + data Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Can't convert 'bytes' object to str implicitly >>> text + data.decode("utf-8") 'Fußbälle sind rund' >>> text.encode("utf-8") + data b'Fu\xc3\x9fb\xc3\xa4lle sind rund'

# Unicode i GTK+

GTK+ använder UTF-8-kodade strängar för all text. Detta betyder att om du anropar en metod som returnerar en sträng kommer du alltid erhålla en instans av typen `str`. Detsamma gäller metoder som förväntar sig en eller flera strängar som parameter, de måste vara UTF-8-kodade. För bekvämlighet kommer dock PyGObject automatiskt konvertera alla unicode-instanser till str om de tillhandahålls som argument:

>>> from gi.repository import Gtk >>> label = Gtk.Label() >>> unicode_string = u"Fu\u00dfb\u00e4lle" >>> label.set_text(unicode_string) >>> txt = label.get_text() >>> type(txt) <type 'str'>

Vidare skulle:

>>> txt == unicode_string

returnera `False`, med varningen `__main__:1: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal` (`Gtk.Label.get_text()` kommer alltid returnera en `str`-instans; därför är `txt` och `unicode_string` inte lika).

Detta är särskilt viktigt om du vill internationalisera ditt program med `gettext`. Du måste säkerställa att `gettext` kommer returnera UTF-8-kodade 8-bitars strängar för alla språk.

I allmänhet rekommenderas det att inte använda `unicode`-objekt i GTK+-program överhuvudtaget och endast använda UTF-8-kodade :class:`str`-objekt då GTK+ inte är helt integrerat med `unicode`-objekt.

Strängkodning är mer konsekvent i Python 3.x, för PyGObject kommer automatiskt koda/avkoda till/från UTF-8 om du skickar med en sträng till en metod eller om en metod returnerar en sträng. Strängar, eller text, kommer alltid endast att representeras som instanser av `str`.

# Referenser

Hur du hanterar strängar - GTK+ 3-handledningen för Python