Ohjelmoidessa on usein tarvetta luoda objekteja, joilla on joukko nimettyjä kenttiä. Python tarjoaa tähän useita vaihtoehtoja, joista dict-rakenne on ehkäpä yleisin, mutta hieman hankala kaikkine lainausmerkkeineen, varsinkin kenttiin myöhemmin viitatessa:

article = {'title':'Otsikko', 'body':'Leipäteksti'}
print article['title'], article['body']


Toinen vaihtoehto on toteuttaa pieni luokka, joka asettaa samat kentät attribuuteiksi. Mutta se on työlästä, koska joutuu kirjoittamaan init-metodin, jos haluaa luoda objekteja yhdellä rivillä:

class Article(object):
    def __init__(self, title, body):
        self.title = title
        self.body = body

article = Article(title='Otsikko', body='Leipäteksti')
print article.title, article.body


Kevyempi kompromissi on luoda vain tyhjä luokka, mutta silloin joutuu asettamaan attribuutit yksitellen:

class Article(object):
    pass

article = Article()
article.title = 'Otsikko'
article.body = 'Leipäteksti'
print article.title, article.body


Ehkäpä kaikkein näppärin vaihtoehto, jonka juuri bongasin Hacker Newsistä, on käyttää valmista collections.namedtuple-rakennetta. Namedtuplella määritelty luokka on optimoitu kevyeksi, staattiseksi container-objektiksi, jossa on kiinteä joukko kenttiä, joiden arvoja ei voi muuttaa. Objekteihin ei siis voi lisätä uusia kenttiä lennossa, ja objekteja luodessa kaikille kentille on annettava arvot:

from collections import namedtuple
Article = namedtuple('Article', ['title', 'body'])
article = Article(title='Otsikko', body='Leipäteksti')
print article.title, article.body


Jos myöhemmin huomaa, että rakenteesta on tarvetta tehdä dynaamisempi, niin namedtuple-määrittely on aika helppoa refaktoroida oikeaksi luokaksi. Sen voi myös periä, jolloin uusi luokka saa kyvyn lisätä attribuutteja, vaikka konstruktorissa onkin yhä pakko määritellä kaikki alkuperäiset:

class MyArticle(Article):
    pass

article = MyArticle(title='Otsikko', body='Leipäteksti')
article.unread = False
print article.title, article.body, article.unread


Oma periaatteeni on, että kuhunkin tilanteeseen kannattaa soveltaa siihen parhaiten soveltuvaa tekniikkaa. Jokaisesta asiasta ei tarvitse aina väkisin tehdä perinteistä luokkaa.

Published 18.3.2012