Python 3/Luokka
Koodi
muokkaaKoodi, jossa on kaksi luokkaa. Ei ole niin monimutkainen kuin miltä näyttää.
class Rect:
def __init__(self, width, height):
self.width, self.height = width, height # voi tehdä samalla rivillä
def draw(self, char):
for i in range(self.height):
print (self.width * char)
class Triangle:
def __init__(self, side):
self.side = side
def draw(self, char):
width = self.side
for i in range(self.side):
width -= 1
indentation = self.side - width # indentation on kolmion kavennus
print (indentation * ' ' + width * char * 2)
Kutsuminen
muokkaa1. suoraan
Rect(20, 10).draw('O')
Triangle(10).draw('X')
2. olion, ilmentymän (engl. instance) avulla
sq = Rect(20, 10)
sq.draw('O')
tr = Triangle(10)
tr.draw('X')
Tulostaa: Neliön ja sen perään kolmion.
OOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOO
XXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXX
XXXXXXXXXXXX
XXXXXXXXXX
XXXXXXXX
XXXXXX
XXXX
XX
Ohjeteksti
muokkaaLuokalle, samoin kuin funktioille ja moduuleille, voi kirjoittaa ohjetekstin yksittäisenä merkkijonona välittömästi luokan sisälle.
class Rect:
"""Luokka neliöiden tulostamiseen.
Parametrit:
width: neliön leveys
height: neliön korkeus
"""
def __init__(self, width, height):
self.width, self.height = width, height
def draw(self, char):
"""Piirtää neliön annetulla merkillä.
Parametrit:
char: merkki, jolla neliö tulostetaan
"""
for i in range(self.height):
print (self.width * char)
Ohjetekstiin pääsee käsiksi help-komennolla komentotulkistaa, pydoc-työkalulla ja luokan jäsenestä __doc__. Tässä oletetaan, että koodi tallennettiin tiedostoon nimeltä shapes.py.
>>> help(shapes.Rect)
Tulostaa
Help on class Rect in module shapes: class Rect(builtins.object) | Rect(width, height) | | Luokka neliöiden tulostamiseen. | | Parametrit: | width: neliön leveys | height: neliön korkeus | | Methods defined here: | | __init__(self, width, height) | Initialize self. See help(type(self)) for accurate signature. | | draw(self, char) | Piirtää neliön annetulla merkillä. | | Parametrit: | char: merkki, jolla neliö tulostetaan | | ---------------------------------------------------------------------- | Data descriptors defined here: | | __dict__ | dictionary for instance variables (if defined) | | __weakref__ | list of weak references to the object (if defined)
Ohjetekstien muotoiluun on monia erilaisia käytäntöjä.
Luokan periyttäminen toisesta luokasta
muokkaaOlemassa olevaa luokkaa voi laajentaa tai muuttaa periyttämällä siitä uuden luokan. Peritty luokka kirjoitetaan sulkuihin luokan nimen perään. Perivä luokka sisältää kaikki samat metodit kuin kantaluokkakin, mutta voi sisältää uusia metodeja tai muuttaa olemassa olevia.
class Shape:
def __init__(self, width, height):
self.width = width
self.height = height
class Rect(Shape):
def __init__(self, width, height):
pass
Kantaluokan metodeja voi tarvittaessa kutsua perivän luokan sisällä super
-funktion avulla.
class Rect(Shape):
def __init__(self, width, height):
super().__init__(width, height)
Jäsenmuuttujat
muokkaaJokaisella luokan instanssilla voi olla omia muuttujiaan. Niihin, samoin kuin instanssin metodeihin, viitataan olion sisällä self
-avainsanalla.
class Rect():
def __init__(self, width, height):
self.width = width
self.height = height
Olion ulkopuolelta niihin viitataan muodossa olio.jäsen.
>>> s = Rect(10, 15)
>>> s.height
15
Yksityiset jäsenmuuttujat ja metodit
muokkaaYksityinen jäsenmuuttuja on olion jäsen, johon ei voi viitata olion ulkopuolelta. Jäsenmuuttujan voi merkitä yksityiseksi aloittamalla sen nimen kahdella alaviivalla. Tämä on ainoastaan käytäntö eikä se kokonaan estä muuttujan käyttämistä ulkopuolelta. Sen nimi ainoastaan muutetaan toiseksi, ettei siihen pääse käsiksi alkuperäisellä nimellä.
class Rect():
def __init__(self, width, height):
self.__area = width * height
Kirjoitussuojatut jäsenmuuttujat, getterit ja setterit
muokkaaJäsenmuuttujan voi tehdä kirjoitussuojatuksi tekemällä sille esimerkiksi yksityisen taustamuuttujan ja @property
-dekoraattorilla merkityn lukumetodin (getter).
class Rect():
# ...
@property
def area(self):
return self.height * self.width
Tällaista ominaisuutta (property) käytetään kuten jäsenmuuttujaa.
>>> s = Rect(10, 10)
>>> s.area
100
Kirjoitussuojattuun muuttujaan voi antaa kontrolloidun pääsyn tekemällä muuttujalle kirjoitusmetodin (setter) @x.setter
-dekoraattorilla. X tarkoittaa tässä hakumetodin nimeä.
class Rect():
# ...
@area.setter
def area(self, value):
import math
self.height = math.sqrt(value)
self.width = math.sqrt(value)
>>> s.area = 121
>>> s.height
11
Ominaisuudella voi olla lisäksi poistometodi (deleter), joka tehdään samaan tapaan kuin setteri @x.deleter
-dekoraattorilla.
Luokkamuuttujat
muokkaaLuokkamuuttujat määritellään heti luokan sisällä kuten esim. funktioiden sisäiset muttujat. Nämä ovat kaikille luokan instansseille yhteisiä.
class Rect(Shape):
unit = "cm"
def __init__(self, width, height):
pass
Huomaa, että luokkamuuttujat jaetaan luokan instanssien kesken. Jos luokkamuuttuja on muu kuin yksinkertainen arvo, muuttujan muuttaminen näkyy kaikilla luokan instansseilla.
class Esim:
lst = []
def __init__(self, name):
self.name = name
self.lst.append(name)
a = Esim("a")
b = Esim("b")
print("a:", a.name, a.lst)
print("b:", b.name, b.lst)
Tulostaa
a: a ['a', 'b'] b: b ['a', 'b']
Luokkametodit
muokkaaKun metodi ei käytä luokan instanssin jäsenarvoja eikä muuta sitä, mutta liittyy silti lähteisti tyyppiin, voi metodista tehdä luokkametodin. Luokkametodeihin on Pythonissa kaksi dekoraattoria @staticmethod
ja @classmethod
. Niiden ero on siinä, että @classmethod
in ensimmäinen parametri on luokkatyyppi, kun taas @staticmethod
on kuin tavallinen funktio.
class Rect(Shape):
def __init__(self, width, height):
super().__init__(width, height)
@staticmethod
def make(width, height):
return Rect(width, height)
Staattista metodia kutsutaan luokan nimellä. Tosin sitä voi myös kutsua instanssin kautta.
>>> Rect.make(25, 25)
<__main__.Rect object at 0x7fc13a7b5c40>
Olion esittäminen merkkijonona
muokkaaLuokasta voi tehdä tulostusystävällisen toteuttamalla sille __repr__- tai __str__-metodit, jotka palauttavat luokan kuvauksen merkkijonona. Esimerkiksi print-funktio käyttää __str__-metodia muuttamaan olion merkkijonoksi, kun sille annetaan jokin olio argumentiksi. Metodi __repr__ on tarkoitettu palauttamaan mahdollisimman tarkka kuvaus olion sisällöstä mielellään Pythonin synaksia jäljittelevässä muodossa, josta vastaavan olion voisi luoda. Jos tämä ei ole mahdollista, tulisi palauttaa kulmasulkeiden väliin tulostettu muu hyödyllinen kuvaus. Metodi __str__ on tarkoitettu tulostamaan olio ihmisystävällisemmässä muodossa. Jos __str__-metodia ei ole toteutettu, käytetään __repr__-metodia.
class Rect():
# ...
def __repr__(self):
return "Rect(width=10, height=5)"
def __str__(self):
return "10×5 rectangle"
>>> rect = Rect(3, 4)
>>> print("Muoto:", rect)
Muoto: 10×5 rectangle
>>> str(rect)
'10×5 rectangle'
Aiheesta muualla
muokkaa- Python-kielisen_ohjelmoinnin_perusteet (Wikiopiston opintopiirin opiskeluohjeita)
Johdanto: | |
---|---|
Tietotyypit ja tietorakenteet: |
Luvut - Merkkijonot - Lista - Monikko (tuple) - Sanakirja - Joukko (set) |
Ohjausrakenteet | |
Muut kielen rakenteet: |
Moduuli - Luokka - Funktio - Virheidenhallinta - Tiedosto |
Graafinen käyttöliittymä: | |
Harjoitustehtäviä: | |
Lisätiedot ja lähteet: |