Python 101
Perusteet
MissÀ ajetaan?
Docker
Aivan kuten aiemmissa osioissa kÀsitellyt kielet, myös Python-kieliset skriptit voidaan ajaa Docker-kontissa. TÀmÀ on, aivan kuten ennenkin, kannattavaa jos teet jotakin riskialtista, kuten tuhoat tiedostoja. Kontti mahdollistaa ns. "clean slate" -ympÀristön, jossa ei ole mitÀÀn ylimÀÀrÀistÀ.
Lokaalisti
Python on valmiiksi asennettuna Ubuntussa ja monissa muissa Linux-jakeluissa. Windowsissa Pythonia ei ole valmiiksi asennettuna, mutta sen voi ladata ja asentaa Pythonin kotisivuilta. Asennuksen jÀlkeen Python on kÀytettÀvissÀ komentoriviltÀ, kunhan muistat aktivoida Add Python to PATH -valinnan asennuksen aikana.
Paketinhallinta... not today
Kun luot Python-ohjelmaa tai -kirjastoa, kÀytÀt todennÀköisesti virtuaaliympÀristöjÀ tai jopa paketinhallintaaohjelmia, kuten Python Poetry tai uv.
Kun kirjoitat skriptiÀ, on jossain mÀÀrin oletettavaa, ettÀ kÀytÀt sitÀ Python-versiota, mikÀ sattuu olemaan asennettuna binÀÀrissÀ /usr/bin/python3.
TÀssÀ luvussa emme luo ohjelmia vaan irrallisia skriptejÀ. Pyrimme pitÀmÀÀn asiat mahdollisimman yksinkertaisina, joten emme kÀytÀ kohdekoneessa virtuaaliympÀristöjÀ, paketinhallintaa, emmekÀ edes asenna pip-paketteja. KÀytÀmme sitÀ Python-versiota, mikÀ sattuu olemaan asennettuna. Lokaalissa koneessa saatamme asentaa paketteja, jotta meidÀn ympÀristömme vastaa sitÀ, mikÀ Debianissa on vakiona.
Python on monilta osin cross-platform, joten skriptit toimivat samalla tavalla riippumatta siitÀ, ajatko niitÀ Windowsissa, Linuxissa vai macOS:ssÀ. Esimerkiksi hakemistopolut kÀyttÀytyvÀt pathlib-kirjaston avulla samalla tavalla riippumatta kÀyttöjÀrjestelmÀstÀ: Path on alustasta riippuen joko WindowsPath tai PosixPath.
Warning
Eroja tosin silti löytyy! Esimerkiksi tiedostoja kirjoittaessa kannattaa olla skarppina, ettÀ mÀÀritÀt eksplitiittisesti tiedoston enkoodauksen, sillÀ Windowsissa oletusenkoodaus on win-1252, kun taas Linuxissa ja macOS:ssÀ se on utf-8.
Myös Linux-jakelut voivat yllÀttÀÀ muutoksillaan. Debianissa (ja myös Ubuntussa) on kÀytössÀ dist-packages-hakemisto, joka ei ole standardi Pythonin osalta. TÀmÀ voi aiheuttaa esimerkiksi sen, ettÀ Ubuntu-kÀyttÀjÀt luulevat requests-kirjaston olevan osa Pythonin Standard LibraryÀ.
MikÀ Python on?
Vapaasti suomennettu What is Python? Executive Summary on seuraava:
Quote
Python on tulkattava, olio-ohjelmointiin perustuva korkean tason ohjelmointikieli. Sen monipuoliset tietorakenteet, dynaaminen tyypitys ja sidonta tekevÀt siitÀ erinomaisen nopeaan sovelluskehitykseen sekÀ skriptauskieleksi eri komponenttien yhdistÀmiseen. SelkeÀ ja helposti opittava syntaksi parantaa luettavuutta ja vÀhentÀÀ yllÀpitokustannuksia. Python tukee moduuleja ja paketteja, mikÀ edistÀÀ koodin uudelleenkÀyttöÀ. Tulkki ja laaja vakiokirjasto ovat ilmaiseksi saatavilla kaikille merkittÀville alustoille. 1
Pythonin sijasta voisimme yhtÀ hyvin opiskella PerliÀ. Kumpikin kieli ponnistaa samankaltaisesta historiasta eli Unix-skriptauksesta. Aivan kuten python3, myös perl on mitÀ todennÀköisimmin valmiiksi asennettuna jakelussasi. Perl on kenties kotikentÀllÀ skriptauksessaan vahvemmassa asemassa. Pythonin oma dokumentaatio tiivistÀÀ sen nÀin: "As a consequence, Python comes close to Perl but rarely beats it in its original application domain; however Python has an applicability well beyond Perl's niche 2" Me kÀytÀmme Pythonia monista syistÀ, joita yksi on se, ettÀ kurssilla kÀsitelty Ansible on kirjoitettu Pythonilla. Toinen on se, ettÀ opiskelijat ovat usein jo kÀyttÀneet Pythonia jossain muussa yhteydessÀ. Jos halut lukea Pythonin oman nÀkemyksen kielen vahvuuksista, lue esimerkiksi Python Docs: Whetting Your Appetite
Alla on piirakkakuvaajaan laskettuna Python, Perl ja Shell-skriptien sekÀ Linux-binÀÀrien mÀÀrÀ /usr/bin-hakemistossa.
pie showData
title File types in bin
"Python" : 46
"Perl" : 50
"Shell" : 132
"Binaries" : 631
Kuinka tiedostot laskettiin?
Komento on ajettu Multipassilla luodussa virtuaalikoneessa, jossa on arm64 Ubuntu 24.04. Komennon find syntaksi on hieman vaikea tulkita, mutta se suorittaa komennon file <file_1> <file_2> <file_...>. Kyseinen komento tulostaa rivin per tiedosto, joka sisÀltÀÀ pÀÀtellyt tiedostotyypin. NÀmÀ rivit putkitetaan grep-komennon filtteröitÀvÀksi, ja lopulta lasketaan filtterin lÀpÀisseet rivit.
$ # Count Python scripts in /bin
$ find /usr/bin -type f -exec file {} \+ | cut -d: -f2 | grep -i "python" | wc -l
46
$ # Count Perl
$ find /usr/bin -type f -exec file {} \+ | cut -d: -f2 | grep -i "perl" | wc -l
50
$ # Count Shell scripts
$ find /usr/bin -type f -exec file {} \+ | cut -d: -f2 | grep -i "shell" | wc -l
132
$ # Count binaries
$ find /usr/bin -type f -exec file {} \+ | grep "ELF" | wc -l
631
Erot shelleihin
Huomaa, ettÀ Python ei kÀyttÀydy shellinÀ samalla tavalla kuin Bash tai PowerShell. Pythonissa toki on olemassa niin sanottu Python Shell, mutta se ei ole shell sanan samassa merkityksessÀ. Pythonin Shell on "REPL" (Read-Eval-Print Loop), joka on interaktiivinen ohjelmointiympÀristö. TÀmÀ tarkoittaa, ettÀ voit kirjoittaa Python-koodia ja nÀhdÀ tuloksen vÀlittömÀsti. MikÀ sen sitten erottaa Bashista tai PowerShellista? Et voi suorittaa jÀrjestelmÀkomentoja suoraan Python ShellissÀ. Eli siis ls ei tulosta hakemiston sisÀltöÀ, cd ei navigoi hakemistossa, docker ei kutsu Docker CLI:tÀ ja niin edelleen.
Selvyyden vuoksi tÀytyy painottaa, ettÀ vaikka emme voi kutsua PATH:ssa olevia binÀÀrejÀ suoraan Python ShellistÀ, voimme kutsua niitÀ subprocess-moduulin avulla. NÀin myös tulemme kurssin aikana tekemÀÀn.
Kuva 1: Python Shell on interaktiivinen ohjelmointiympÀristö, jossa voit kirjoittaa Python-koodia ja nÀhdÀ tuloksen vÀlittömÀsti. Huomaa, ettÀ se kÀynnistetÀÀn tyypillisesti jonkin shellin child-prosessina: kuvan tapauksessa Bashin. Interaktiivista shelliÀ voi kÀyttÀÀ leikkikenttÀnÀ, mutta tyypillisesti Python ajetaan skriptinÀ.
EnsimmÀinen kontti
Aivan kuten edellisissÀ osioissa, myös Python-skriptit voidaan ajaa Docker-kontissa, mutta image pitÀÀ valita siten, ettÀ Python 3 on asennettuna.
Komento suorittaa imagen default Cmd:n, joka on python3. Toisin sanoen kÀynnistÀt Python Shellin. Vaihtoehtoisesti voit antaa sille parametriksi polun skriptiin. TÀhÀn tutustumme kurssin aikana.
Skripti
SisÀltö
Huomaa, ettÀ shebang ei ole sinÀnsÀ osa Pythonia, eikÀ tyypillinen Python-ohjelma sisÀllÀ shebangiÀ. Alustamme on Unix-like, ja teemme skriptiohjelmointia, joten voimme kuitenkin hyödyntÀÀ sitÀ - ja nÀin tekevÀt /usr/bin-hakemiston Python-skriptitkin.
đ Inline Script Metadata
Tulevaisuus
TĂ€mĂ€ on tuore feature ja siksi otsikossa on đ-emoji. Emme kĂ€ytĂ€ ominaisuutta kurssilla, mutta koska se liittyy vahvasti skriptaukseen ja lienee tulevaisuudessa yleinen kĂ€ytĂ€ntö, on hyvĂ€ olla tietoinen siitĂ€.
PEP 723 (Python Enhancement Proposal) toi mukanaan Pythoniin uudistuksen Inline Script Metadata. Kuinka tÀtÀ sitten hyödynnetÀÀn? Alla on esimerkki metadatan muotoilusta skriptin alkuun. SkriptiÀ ei voi ajaa suoraan Python 3.12:lla, vaan avuksi tarvitsee muita työkaluja, kuten uv tai hatch.
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "requests",
# "pydantic",
# ]
# ///
import requests
from pydantic import BaseModel
class Post(BaseModel):
userId: int
id: int
title: str
body: str
# Fetch a dummy Post from REST API using Requests
response = requests.get("https://jsonplaceholder.typicode.com/posts/1")
post = Post.model_validate_json(response.content)
print(post.title)
Jos uv on asennettuna, voit ajaa skriptin seuraavasti:
$ uv run inline_metadata_example.py
Installed 9 packages in 21ms
[INFO] The title: sunt aut facere repellat provident occaecati excepturi optio reprehenderit
Huomaa, ettÀ inline-metadatassa listatut riippuvuudet (ja niiden riippuvuudet) asennettiin automaattisesti vÀliaikaiseen ympÀristöön.
EntÀ kontissa?
Voit toki kokeilla samaa ominaisuutta myös kontissa. Esimerkiksi nÀin:
Ajaminen
Python skriptin voi ajaa joko argumenttina python3-ohjelmalle tai suoraan skriptinÀ, jos shebang on mÀÀritelty, ja tiedosto on ajettava (executable, x file mode).
Bash Python-ajurina
On mahdollista hyödyntÀÀ Python-kieltÀ Bash-skriptissÀ. TÀmÀ on hyödyllistÀ, kun haluat suorittaa jonkin operaation, mikÀ on merkittÀvÀn vaikea toteuttaa Bashilla. Jopa kohtalaisen yksinkertaisissa tapauksissa Python voi edistÀÀ syntaksin selkeyttÀ ja ymmÀrrettÀvyyttÀ - ja tÀmÀ on tÀrkeÀÀ, jos skriptiÀsi joku muu joutuu lukemaan.
Kuvitellaan esimerkki, ettÀ sinun tulee selvittÀÀ, kuinka monta pÀivÀÀ on tietyssÀ kuukaudessa. Mieti hetki, kuinka tÀmÀ voisi onnistua BashissÀ. TÀmÀn jÀlkeen avaa alta vihjelaatikko, jossa on ainakin yksi ratkaisu tÀhÀn.
Vihje: Kuukauden pÀivÀt BashillÀ
Voit toteuttaa tÀmÀn Bashilla kÀyttÀmÀllÀ case-lauseketta. Helmikuu vaatisi kuitenkin karkausvuosien osalta poikkeuksen. TÀmÀ ei ole maailman vaikein ohjelma, ja olet kenties jo aiemmassa harjoituksessa toteuttanut is_leap_year -funktion, jota voisi hyödyntÀÀ tÀssÀ.
Saman voisi toteuttaa Pythonissa rautakoodattuna nÀin:
Voimme upottaa seuraavan Python-rimpsun Bashiin nÀin:
#!/bin/bash -eu
# Usage: days_in_month.sh [month] [year]
month=$1
year=${2:-$(date +%Y)}
n_days=$(python3 -c "
import calendar
print(calendar.monthrange($year, $month)[1])
"
)
echo "Number of days in $month/$year: $n_days"
Warning
Miksi joku siis suosisi natiivia Bash-toteutusta? Yksi syy on, ettÀ Linuxissa on aina jokin POSIX-yhteensopiva shell saatavilla, toisin kuin Python. TyypillisistÀ jakeluista python3 löytyy, mutta konteissa ajetaan usein kovin karsittua imagea. Jos kÀytÀt Pythonia skripteissÀ, sinun pitÀÀ valita oikea image. LisÀksi vuosikymmeniÀ vanha POSIX-yhteensopivuus on melko vakaa verrattuna Pythonin versioyhteensopivuuteen.
KÀytÀnnössÀ tÀssÀ taistelevat siis portability + stability vs. readability + maintainability.
TÀhÀn ei ole absoluuttisesti oikeaa ja vÀÀrÀÀ vastausta.
TehtÀvÀt
TehtÀvÀ: Python informaatiohaku
Muodosta itsellesi katalogi tarpeellisista lÀhteistÀ. Python kehittyy aktiivisesti, joten suosi uusia lÀhteitÀ. Alla pari suositusta, mistÀ aloittaa etsintÀ:
- The Python Standard Library. Pythonin oman dokumentaation Standard Library -osio on korvaamattoman hyvÀ. Pythonin mukana tulevien moduulien dokumentaatio on tÀÀllÀ. Kurssilla kÀytetÀÀn skriptaukseen liittyviÀ moduuleja, joista tÀrkeimpinÀ
os,sys,subprocess,argparsejalogging. MitÀ mahtaa tehdÀ esim.calendar? EntÀgetpass? - DevHints.io: Python. Cheat sheet, joka sisÀltÀÀ kielen perusasiat yhdessÀ paketissa. TÀmÀn ja ylemmÀn lÀhteet avulla saat jo yllÀttÀvÀn paljon aikaiseksi.
- Python strftime cheatsheet. Jos/kun pÀÀdyt pelaamaan pÀivÀmÀÀrien formatoinnin kanssa, tÀmÀ cheat sheet on nopea apu.
- Python for DevOps: Learn Ruthlessly Effective Automation. Kirja löytyy korkeakoulun Finna-kirjastosta digitaalisena kopiona. Voit lukea sitÀ selaimessa.
Skriptaus on niin laaja kÀsite, ettÀ hakusanoilla "python scripting" ei yleensÀ löydÀ mitÀÀn hyödyllistÀ. Tee siis ensin tarkempi suunnitelma siitÀ, mitÀ aiot tehdÀ, ja muodosta tÀmÀn avulla hakusanasi. Kielimallit voivat auttaa hahmottamaan, millÀ kirjastoilla haluamasi ratkaisu hoituu.
Jos olet valmis sijoittamaan opiskeluusi rahaa, myös seuraavat lÀhteet voivat olla varteenotettavia:
- đ° Humble Bundle. Sivustolla on ajoittain tarjolla kirjoja, jotka kĂ€sittelevĂ€t Bash-skriptauksen perusteita. Tarjonta vaihtelee jatkuvasti, joten on tuurista kiinni, löytyykö sieltĂ€ nyt mitÀÀn hyödyllistĂ€. Kirjapaketit maksavat yleensĂ€ halvimmillaan noin 1-20 euroa.
- đ° O'Reilly. Kirjastoon kuuluu useiden eri julkaisijoiden kirjoja: O'Reilly, No Starch Press, Manning Publications, Packt, Apress ja monet muut. Luettavissa kuukausimaksulla.
- đ° Real Python: Subprocess. Real Python on maksullinen sivu, mutta maltillisen mÀÀrĂ€n artikkeleita saa lukea ilmaiseksi. Kun tiedĂ€t, mitĂ€ haluat, voit etsiĂ€ tietoa tarkemmin tÀÀltĂ€. TĂ€ssĂ€ linkitetty artikkeli kĂ€sittelee
subprocess-moduulia, joka on tÀrkeÀ osa Python-skriptauksen työkalupakkia.
