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.