Python
Sissejuhatus
Python (ingl. k. püüton) http://www.python.org/ on suhteliselt populaarne programmeerimiskeel, mille lõi Guido van Rossum http://en.wikipedia.org/wiki/Guido_van_Rossum 1980 aastate lõpus ja millele peetakse iseloomulikuks
- kasutamise lihtsus, st kiiresti õpitav ja saab kiiresti jõuda kasutatavate tulemusteni
- keele küpsus
- sobib mitmekesiste ülesannete lahendamiseks (ingl. k. general purpose language)
- sunnib kasutajat kirjutama nö loetavat programmi
- Python on skriptimiskeel (ingl. k. scripted language) st programmid on koheselt käivitatavad ja ei vaja kompileerimist
- Python sisaldab objektorienteeritud programmeerimise (OOP) võimalusi, kuid neid ei pea tingimata kasutama (käesoleva teksti punkt Python#OOP on pühendatud sellele)
- Python on vaba tarkvara
2010 aastal on levinud kasutada kahte erinevat Python keele põlvkonda, sõltuvalt kasutusalast või kasutamise asjaoludest võib see olla oluline, kumba konkreetsel juhul eelistada
- 2.x - juba pikka aega kasutuses olnud versioon, mida jätkuvalt toetatakse
- 3.x - uuem versioon, millega reeglina vana versiooni jaoks kirjutatud programmid ei tööta; nt print direktiiv ja teksti vs binari failide käsitluse osa on oluliselt muutunud
Mõned populaarsed vaba tarkvaralised Pythoni rakendused on näiteks
- Mailman - postiloendi serveri (ingl. k. listserver) tarkvara
- Trac - veebipõhine veahalduse ja versioonikontrolli tarkavara
- Zope, Plone - veebikeskkonnad
Pythonis valmistatud tarkvara on loetletud aadressil http://en.wikipedia.org/wiki/List_of_Python_software.
Järgnev tekst sisaldab kahte osa
- keele vahendite tutvustus - tegu ei ole ammendava käsitlusega, kuid piisavaga selleks, et asuda Pythonit kasutama ning et tekiks ettekujutus Pythoni võimalustest
- nö kokaraamatu (ingl. k. cookbook) osa - keskendutud on süsteemiadministreerimisel vajalikele kasutusjuhtumitele, nt meili saatmine, http, ldap ja dns päringute esitamine, kodeeringutega tegelemine jms kasutades seejuures Pythoni teekide võimalusi.
Esitatud tekst kehtib v. 2.x kohta kui teksti sees ei ole versiooni täpsustatud.
Pythoni paigaldamine
Debian Lenny paketihalduses on olemas kaks Pythoni versiooni
- 2.5.2 - vaikimisi
- 2.4.6 - võimalik lisaks paigaldada
Python v. 2.5.2 paigaldmiseks sobib öelda (tegelik paketinimi on python2.5)
# apt-get install python
Programmeerimine Pythonis
Üldiselt võib väita, et programm 'teeb midagi millegagi', konkreetsemalt sobib kujutleda Pythoni kasutamist sellise hierarhiana
- programmid koosnevad moodulitest
- moodulid koosnevad lausetest (ingl. k. statement)
- laused koosnevad avaldistest (ingl. k. expression)
- avaldised tekitavad ja töötlevad objekte
Python on
- dünaamilise tüübiskeemiga (ingl. k. dynamically typed) keel - programmi käivitamisel ajal (ingl. k. runtime) toimub tüüpide üle otsustamine; st praktiliselt, et nt muutujate väärtustamisel ei pea nende tüüpe kirjeldama
- tugeva tüübiskeemiga (ingl. k. strongly typed) keel - erinevat tüüpi muutujatega ei saa teha teatud operatsioone, nt liita arv ja sõne
Pythoni interpretaator
Pythoni interpretaatori kasutamine interaktiivses režiimis toimub selliselt
$ python Python 2.5.2 (r252:60911, Jan 24 2010, 14:53:14) [GCC 4.3.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> a="tervist" >>> print a tervist >>> Ctrl+D $
Interpretaator sobib nt kalkulaatorina kasutamiseks
>>> 21.0/8 2.625
Etteruttavalt saab öelda, et sarnaselt saab ka nt PostgreSQL andmebaasiga suhelda
>>> import psycopg2 >>> conn = psycopg2.connect("dbname='baasinimi' user='kasutajanimi' host='192.168.10.51' password='parool' port='5432'") >>> cur = conn.cursor() >>> cur.execute("select version();"); >>> read = cur.fetchall() >>> for rida in read: ... print rida ... ('PostgreSQL 8.4.21 on x86_64-pc-linux-gnu, compiled by GCC gcc-4.4.real (Debian 4.4.5-8) 4.4.5, 64-bit',)
Pythoni skript
Pythoni skript esineb tekstifaili kujul, kusjuures sisu kirjutamisel tuleb jälgida, et tulemust mõjutab ka ridade alguses kasutatud tühikute hulk, st taane (ingl. k. intendation). Nt selline skript kirjutab välja arvud ühest kolmeni
for i in range(3): print i + 1
kus
- range(3) funktsioon tekitab loendi elementidega 0, 1, 2 ja 3
- for-kordus tegeleb järjekorras kõigi elementidega
- print esitab i + 1 avaldise väärtuse iga for korduse jaoks, kusjuures print on trepitud (ingl. k. to intendate)
Skripti käivitamiseks sobib öelda
$ python skript.py 1 2 3
Alternatiiviks on lisada faili algusse rida interpretaatori nimega
#!/usr/bin/python for i in range(3): print i+1
ning muuta fail käivitatavaks
$ chmod 0755 skript.py
ning käivitada
$ ./skript.py
Lisaks töötavatele ridadele võib skriptis esineda kommentaare, kõike # märgist paremale jäävat käsitletakse kommentaarina.
Sõne-operatsioonid
Sõnedega (ingl. k. string) saab teha nt selliseid operatsioone
- omistada muutujale ja esitada
linn = "Tartu" print linn
- liita
linn = "Tartu" print "Asukoht " + linn
- küsida elementi, vastatakse 'r'
sone = "Tartu" print sone[2]
Andmestruktuurid
Pythonis kasutatavad enamlevinud nn sisse-ehitatud (ingl. k. built-in) andmestruktuurid on
- sõne - järgnevus tähti-numbreid-muid-sümboleid
- arv - nt täisarv või ujukomaarv
- loend (ingl. k. list) - ...
- korteež (ingl. k. tuple) - järjestatud hulk, mille elemente ei saa muuta
- sõnastik (ingl. k. dictionary) - mõnedes keeltes tuntud ka kui assotsiatiivne massiiv (ingl. k. associative array, ka hash)
Andmetüüpi saab küsida nii
$ python >>> a=15 >>> type(a) <type 'int'> >>> sone="see on sone sisu" >>> type(sone) <type 'str'>
kus
- väärtustatakse muutujad, a ja sone
- küsitakse muutuja tüüpi, vastuseks saadakse vastavalt int ja str
Sõne
Sõne (ingl. k. string) on järgnevus tähti-numbreid-muid-sümboleid
'abcdefgh'
Arv
Arv (ingl. k. number) võib olla nt täisarv või ujukomaarv
15
Kuna Python on tugeva tüübiskeemiga keel, siis nt ei saa liita arve ja sõnesid, eelnevalt tüleb tüüp teisendada, nt
print 'mina tulen kell ' + str(10)
Loend
Loend (ingl. k. list) on järjestatud hulk, järjekorra algusnumbriga 0
loend = ['yks', 'kaks', 'kolm']
Loendi elemendi 'kaks' poole pöördumine toimub selliselt
print loend[1]
Loendiga saab sooritada mitmeid iseloomulikke tegevusi, nt
- järjekorra ümberpööramine
print loend.reverse()
- elemendi lisamine
loend.append('neli')
- elemendi jrk numbri küsimine
loend.index('kaks')
- loendi saab täita loendi genereerimise (ingl. k. list comprehension) teel võttes aluseks olemasoleva loendi
loend = [ 10, 20, 30 ] comp = [ 3*x for x in loend ] for i in comp: print i
või sisu arvutusest genereerida
comp = [ 2*x for x in range(10) ] for i in comp: print i
- Massiliselt saab järjetsikuseid elemente eemaldada, seejuures alles jäävate jrk numbrid muutuvad
loend[0:2]=[]
- Tühja loendi loomiseks sobib öelda, seejärel saab kasutada käsku append
loend = [] loend.append('elemendi sisu')
- Olemasolevast loendist koopia tegemiseks
loend2 = list(loend)
Korteež
Korteež (ingl. k. tuple) on järjestatud hulk, mis erineb loendist nt selle poolest, et selle on oluliselt vähem funktsionaalsust, mis põhiliselt tuleneb asjaolust, et korteeži elemente ei saa muuta
k = ('yks', 'kaks', 'kolm')
Korteeži saab kasutada for-korduse juures ning tema elemente saab järjekorra alusel küsida, nt
print k[2]
Loendi teisedab korteežiks funktsioon tuple()
k = tuple(loend)
Sõnastik
Sõnastik (ingl. k. dictionary) on key-value paaridest koosnev järjestamata hulk
sonastik = { 'priit': 167, 'mart': 196 }
Sõnastiku elemendi väärtuse esitamine toimub nii
print sonastik['priit']
Hulk
Hulk (ingl. k. set) on järjestamata kogum elemente
hulk1 = set(['essa', 'tessa', 'kossa', 'nessa'])
Hulkadega saab teha nt selliseid tehteid
- ühend (summa)
print hulk1 | hulk2
- ühisosa (lõige, korrutis)
print hulk1 & hulk3
Nagu alguses kasutatud, loendi teisendamiseks hulgaks sobib kasutada set funktsiooni
hulk = set(loend)
Ning hulga teisendamine loendiks (kusjuures tulemuse järjestusele ei maksa toetuda) toimub funktsiooniga list
loend = list(hulk)
Failioperatsioonid
Failioperatsioonid tegelevad failist lugemise ja faili kirjutamisega.
Lugemine
Tekstifailist lugemiseks sobib kasutada nt sellist järgnevust
for rida in open ('urlid.txt'): print rida.rstrip()
kus
- open ('urlid.txt') - avab tekstifaili
- rstrip() eemaldab rea lõpust reavahetuse märgi
- lugemine toimub for-korduse abil rida haaval
Kirjutamine
Tekstifaili kirjutamiseks sobib kasutada nt sellist järgnevust
read=('loomaaed.tartu.ee', 'kuutorvaja.eenet.ee', 'www.eesti.ee') myfile = open ('urlid','w') for rida in read: myfile.write (rida + '\n') myfile.close()
kus
- myfile = open ('urlid','w') - tekstifail urlid avatakse lugemiseks ja kirjutamiseks
- read - on korteeži element, mis on loendi moodi konstruktsioon, kuid mille sisu ei saa peale moodustamist muuta
- kirjutamine toimub for-korduse abil rida haaval
Tingimused
Pythonis saab kasutada selliseid tingimusi
- if-elif-else tingimus
x = 1 if x < 0: print 'Alla nulli' elif x == 0: print 'Null' elif x == 1: print 'Yks' else: print 'Suurem yhest'
Kordused
Pythonis saab kasutada selliseid kordusi
- for-kordus
loend = ['Priit', 'Mart', 'Laa'] for i in loend: print "Tervist " + i
- while-kordus
i = 0 while i < 5: i = i + 1 print i
Kordusest saab tulla välja break abil, nt
l = [ 'essa', 'tessa', 'kossa', 'nessa' ] for i in l: if i == 'kossa': print "if seest print", i break print "if jarel print", i print "for jarel print", i
annab sellise väljundi
$ python skript.py if jarel print essa if jarel print tessa if seest print kossa for jarel print kossa
Funktsioonid
Funktsioonid võimaldavad üldiselt kahte asja
- korraldada programmi osade korduvkasutust
- jagada programmi loogilisteks osadeks
Funktsioon kireldatakse def direktiivi abil, nt selliselt
def korrutamine(x, y): return x * y print korrutamine(15, 3)
kus
- esimesed kaks rida kirjeldavad funktsiooni
- return tagastab funktsiooni väljakutsele väärtuse
- viimases reas toimub funktsiooni väljakutse
Pythoni funktsioonide kohta öeldaks, et nad on polümorfsed, st nad töötavad suvaliste sisendaandmetega eeldusel, et funktsioonis kirjeldatud operatsioone saab sooritada nende andmetega. Nt sobiks ülaltoodud funktsiooni välja kutsuda selliselt
print korrutamine ('mina ', 3)
Funktsiooni dokumentatsioon
Pythoni funktsiooni saab dokumenteerida esitades vahetult def järel kolmekordsete jutumärkide vahel teksti
def korrutamine(x, y): """Korrutaja Korrutab """ return x * y
Sellist dokumentatsiooni saab lugeda nt selliselt
print korrutamine.__doc__
Moodulid
Moodulite abil organiseeritakse programmi teksti kõige üldisemal tasemel. Nt esitatud moodul vastab failile aritmeetika.py ning seal on kirjeldatud üks muutuja ning kaks funktsiooni
$ cat aritmeetika.py pii = 3.14 def liida(x, y): return x + y def lahuta(x, y): return x - y
Seda moodulit kasutab nt selline skript
import aritmeetika print "Pii väärtus on ", aritmeetika.pii print aritmeetika.liida(2, 3)
Mooduli poole pöördumiseks kasutatakse järgnevust 'mooduli-failnimi.moodulis-kirjeldatud-objekt', nagu näitest on näha võib see objekt olla muutuja või funktsioon.
Tehniliselt on kõik Pythoni skriptid moodulid.
Parasjagu kasutada oleva süsteemi moodulirada näeb öeldes
>>> import sys >>> print sys.path [' ', '/usr/lib/python2.5', '/usr/lib/python2.5/plat-linux2', '/usr/lib/python2.5/lib-tk', \ '/usr/lib/python2.5/lib-dynload', '/usr/local/lib/python2.5/site-packages', \ '/usr/lib/python2.5/site-packages', '/usr/lib/pymodules/python2.5']
kus listi esimene element on tegelikult 'kaks ülakoma järjest', mis tähistab käesolevat kataloogi. Importimisel otsib Python otsib moodulid järjest nendest kataloogidest, otsinguteele saab lisada katalooge keskkonnamuutuja PYTHONPATH abil, nt
$ export PYTHONPATH=/opt/python-libs
Moodulis kirjeldatud objektide nimekirja küsimiseks sobib öelda
>>> import moodulinimi >>> dir(moodulinimi) ['__builtins__', '__doc__', '__file__', '__name__', 'korrutaja', 'pii']
Nimeruum
Peale programmi sisse mooduli importimist saab tema objektide poole pöörduda kujul
moodulinimi.objektnimi
Öeldakse, et programmi jaoks on tekkinud mooduli nime ja seal kirjeldatud objektide nimedele vastav nimeruum (ingl. k. namespace).
Paketid
Lisaks failidele saab mooduleid paigutada spetsiaalselt moodulite hoidmiseks moodustatud kataloogidesse. Sellist kataloogi nimetatakse paketiks (ingl. k. package) ja seal peab sisalduma fail __init__.py. Paketi kujul esitatud moodulite laadimiseks tuleb programmis öelda
import katalooginimi
Seejuures täidetakse esmalt __init__.py faili sisu, see fail võib olla ka tühi, ning seejärel kõik kataloogis olevad moodulitele vastavad failid.
Paketi kataloogistruktuur võib olla ka mitmetasemeline, üldiselt toimub moodulis kirjeldatud objektide kasutamine selliselt
katalooginimi1.katalooginimi2.funktsiooninimi()
Mooduli kasutuskoha kontroll
Üldiselt võib olla vaja moodulit nii kasutada importimise teel kui ka otseselt käivitades. Selleks, et neid kahte juhtumit eristada, sobib kasutada mooduli sees ühte if-tingimust ja muutuja nime, mis on erinev sõltuvalt kasutusjuhust. Nt selliselt
pii = 3.14 def liida(x, y): return x + y def lahuta(x, y): return x - y if __name__ == '__main__': print "mind käivitatakse otse"
kus
- __name__ muutuja väärtus on otse käivitamisel '__main___' ning importimisel vastava faili nimi
Baitkood
Skripti poolt kasutatavate moodulite jaoks moodustatakse skripti esmakordsel käivitamisel esmalt baitkood (ingl. k. bytecode) ja see baitkood käivitatakse Pythoni virtuaalsel masinal. Baitkood tekitatakse automaatselt samasse kataloogi mooduliga samanimelise failina, mille nime lõpus on .pyc.
Järngevatel skript käivitamistel kontrollitakse moodulite ja moodulitele vastavate baitkoodi failide viimase muutmise aegu ning selle järgi otsustatakse, kas baitkood tuleb uuesti moodustada. Kui baitkoodi pole vaja moodustada, siis Python kasutab olemasolevat baitkoodi ning skripti käivitamine toimub baitkoodi moodustamisele kuluva aja võrra kiiremini.
Võiks ette kujutada, et baitkood on midagi lähtekoodi ja masinkoodi vahepealset, nt tema kasutamise efektiivsuse mõttes.
HTTP
HTTP päringute tegemiseks on Pythonis kaks teeki
- urllib - kõrgema abstraktsusega teek, mida soovitatakse reeglina kasutajal kasutada, http://docs.python.org/library/urllib.html
- urllib2 - täiendava funktsionaalsusega teek, nt basic auth
- httplib - madalama taseme teek, mida kasutab omakorda ka urllib, http://docs.python.org/library/httplib.html
Skript http päringu vastuse päise elemendi esitamiseks
import httplib conn = httplib.HTTPConnection("www.python.org") conn.request("GET", "/index.html") r1 = conn.getresponse() print r1.getheader('last-modified')
Lihtsa HTTP serveri, mis serveerib üle HTTP käesoleva kataloogi sisu, saab käivitada selliselt
$ python -m SimpleHTTPServer 8080 Serving HTTP on 0.0.0.0 port 8080 ...
Basic auth
import urllib2 auth_handler = urllib2.HTTPBasicAuthHandler() auth_handler.add_password(realm='Tekst millega veebikoht nö tervitab', uri='https://svn.loomaaed.tartu.ee/projektid/', user='priit', passwd='parool') opener = urllib2.build_opener(auth_handler) urllib2.install_opener(opener) f = urllib2.urlopen('https://svn.loomaaed.tartu.ee/projektid/projektinimi/trunk/sql/LoeMind.txt') print f.read(100000)
try-except-else-finally lause
Python võimaldab programmi töös esineda võivaid erindeid (ingl. k. exception) st praktiliselt veasituatsioone püüda try-except lause abil.
Skript
- kirjeldab loendi URLID
- käib läbi loendis URLID toodud hostide /index.html ressursid
- kui ressursi poole ei õnnestu pöörduda püütakse see try/except poolt kinni
import httplib URLID = ('www.python.org', 'kuutorvaja.eenet.ee', 'seda.pole') for i in URLID: try: conn = httplib.HTTPConnection(i) conn.request("GET", "/index.html") except: print "ei saa avada http://" + i + "/index.html" else: r1 = conn.getresponse() print i + " " + r1.getheader('content-length') finally: print "Finaal"
kus
- else täidetakse juhul kui except ei ole rakendunud; koodi paigutamine else alla selle asemel, et paigutada samuti try alla on põhjendatud kuna nii try kontrollib ainult seda mida on vajalik kontrollida
- finally täidetakse igal juhul
Käivitamisel esitatakse nt selline väljund
$ python finaal.py www.python.org 21120 Finaal kuutorvaja.eenet.ee 267 Finaal ei saa avada http://seda.pole/index.html Finaal
with lause
Lühidalt öeldes, with kasutamisel ei ole vaja muretseda ressursside vabastamise pärast, nt avatud fail
with open("urlid.txt") as f: print f.read()
käivitamisel esitatakse faili sisu
$ python skript.py rida 1 rida 2 rida 3
Kasulikud materjalid
Unicode
Pythonis saab töötada Unicode'iga sh UTF-8 kodeeringus tekstiga, http://docs.python.org/howto/unicode.html.
Skript UTF-8 formaadis faili kirjutamiseks (sisuks on Ä ja à tähed)
import codecs file = codecs.open('utf8data.txt', encoding='utf-8', mode='w') size = file.write(u'\u00c3\u0161\u00c4\u0160\u015D\u01FD') size = file.write('\xc4\xc3\n') file.close ()
Kasulikud lisamaterjalid
PostgreSQL andmebaasi kasutamine
Psycopg http://initd.org/psycopg/ võimaldab Pythonist kasutada PostgreSQL andmebaasi. Tarkvara paigaldamiseks Debian operatsioonisüsteemis sobib öelda Pyhton v. 2 puhul
# apt-get install python-psycopg2
ja Pyhton v. 3 puhul
# apt-get install python3-psycopg2
Andmete lugemine
Skript küsib andmebaasi tabelist priit.priidutabel kahte väärtust
import psycopg2 conn = psycopg2.connect("dbname=baasinimi host=192.168.1.247 user=kasutajanimi password=kasutajaparool port=portnumber") cur = conn.cursor() cur.execute("SELECT nimi, vanus FROM priit.priidutabel where nimi = 'Priit Kask';") read = cur.fetchall() for rida in read: print ('Nimi: %s, vanus: %s' % rida) cur.close() conn.close()
kus
- connect() parameeter on ühendussõne
- cur.fetchall() tagastab vastused korteežidena
Andmete sisestamine
Andmete baasi sisestamisel tuleb lisaks öelda commit
import psycopg2 conn = psycopg2.connect("dbname=baasinimi host=192.168.1.247 user=kasutajanimi password=kasutajaparool port=portnumber") cur = conn.cursor() cur.execute("insert into priit.priidutabel (vanus, nimi) values ('28', 'Mart Kask');") cur.close() conn.commit() conn.close()
Binary andmete sisestamine
Binary andmeid hoitakse bytea tüüpi väljas, nt sellises tabelis
CREATE TABLE bitea.tabelinimi(name TEXT, ablob BYTEA);
Andmeid saab sisestada sellise skriptiga
import psycopg2, cPickle connection = psycopg2.connect() cursor = connection.cursor() data = cPickle.dumps('binaarne sisu', 2) sql = "INSERT INTO bitea.tabelinimi VALUES(%s, %s)" cursor.execute(sql, ('esimesevaljavaartus', psycopg2.Binary(data))) connection.commit() cursor.close() connection.close()
ja nt pildi sisestamine
import psycopg2, cPickle conn = psycopg2.connect("dbname=baasinimi host=127.0.0.1 user=postgres password=parool port=5432") cur = conn.cursor() f = open('/tmp/pilt.jpg', 'rb') binary = f.read() sql = "insert into testskeem.testtabel (pilt) values (%s)"; cur.execute(sql, (psycopg2.Binary(binary),)) cur.close() conn.commit() conn.close()
Binary andmete väljastamine
#!/usr/bin/python import psycopg2 conn = psycopg2.connect("dbname=baasinimi host=10.0.13.170 port=5432 user=kasutaja password=parool") cur = conn.cursor() cur.execute("SELECT file_data from document_file where id=143709") read = cur.fetchone() open('/tmp/failnimi.jpeg', 'wb').write(str(read[0]))
Server-side kursori kasutamine
Järgmine skript
- loeb tabelist failid kaks välja, faili_id (int) ja sisu (bytea)
- kasutab server-side kursorit, skripti töötamise ajal on serveris näha sql käsk; sellise kursori kasutamise eeliseks on, et saab ühe select lause ja for kordusega kordusega kõik ära teha, samal ajal ei ammendata serveri ega kliendi arvuti ressurssi
fetch forward 1 from kursori_nimi
- arvutab bytea andmetele sha1 kontrollsumma
import psycopg2, cPickle, hashlib, psycopg2.extras conn = psycopg2.connect("dbname=baasinimi host=baas.loomaaed.tartu.ee) cur = conn.cursor('kursori_nimi', cursor_factory=psycopg2.extras.DictCursor) cur.execute("select faili_id, sisu from public.failid") for record in cur: print record[0], hashlib.sha1(str(record[1])).hexdigest() cur.close() conn.commit() conn.close()
Kasulikud lisamaterjalid
Kasulikud lisamaterjalid
MySQL andmebaasi kasutamine
MySQL-Python http://mysql-python.sourceforge.net/ võimaldab Pythonist kasutada MySQL andmebaasi. Tarkvara paigaldamiseks Debian operatsioonisüsteemi sobib öelda
# apt-get install python-mysqldb
Andmete lugemine
Skript küsib andmebaasi tabelist priit.priidutabel kahte väärtust
import MySQLdb conn = MySQLdb.connect(db="baasinimi" host="192.168.1.247" user="kasutajanimi" passwd="kasutajaparool" port=portnumber) cur = conn.cursor() cur.execute("SELECT nimi, vanus FROM priit.priidutabel where nimi = 'Priit Kask';") read = cur.fetchall() for rida in read: print ('Nimi: %s, vanus: %s' % rida) cur.close() conn.close()
kus
- connect() parameeter on ühendussõne
- cur.fetchall() tagastab vastused korteežidena
Andmete sisestamine
Andmete baasi sisestamisel tuleb lisaks öelda commit
import MySQLdb conn = MySQLdb.connect(db="baasinimi" host="192.168.1.247" user="kasutajanimi" passwd="kasutajaparool" port=portnumber) cur = conn.cursor() cur.execute("insert into priit.priidutabel (vanus, nimi) values ('28', 'Mart Kask');") cur.close() conn.commit() conn.close()
Oracle andmebaasi kasutamine
cx_Oracle http://cx-oracle.sourceforge.net/ võimaldab Pythonist kasutada Oracle andmebaasi (antud juhul v. 2.6.6 Debian Squeeze keskkonnas). Paigaldamiseks tuleb
- tekitada nö tavapärasel viisil Oracle_Instant_Client /opt/instantclient kataloog ning moodustada seal link
# ln -s libclntsh.so.11.1 libclntsh.so
- paigaldada cx_Oracle kompileerimiseks vajalikud paketid
# apt-get install build-essential python-dev libaio-dev
- seadistada keskkonnamuutujad
# export LD_LIBRARY_PATH=/opt/instantclient # export ORACLE_HOME=/opt/instantclient # export TNS_ADMIN=/opt/instantclient
- Pakkida cx-oracle lahti kuhugi ja öelda seal
# python setup.py build # python setup.py install
Tulemusena tekivad süsteemi kataloogi /usr/local/lib/python2.6/dist-packages failid
# find cx_Oracle-5.1.2-py2.6-linux-x86_64.egg/ -type f cx_Oracle-5.1.2-py2.6-linux-x86_64.egg/cx_Oracle.py cx_Oracle-5.1.2-py2.6-linux-x86_64.egg/cx_Oracle.pyc cx_Oracle-5.1.2-py2.6-linux-x86_64.egg/EGG-INFO/native_libs.txt cx_Oracle-5.1.2-py2.6-linux-x86_64.egg/EGG-INFO/SOURCES.txt cx_Oracle-5.1.2-py2.6-linux-x86_64.egg/EGG-INFO/top_level.txt cx_Oracle-5.1.2-py2.6-linux-x86_64.egg/EGG-INFO/zip-safe cx_Oracle-5.1.2-py2.6-linux-x86_64.egg/EGG-INFO/dependency_links.txt cx_Oracle-5.1.2-py2.6-linux-x86_64.egg/EGG-INFO/PKG-INFO cx_Oracle-5.1.2-py2.6-linux-x86_64.egg/cx_Oracle.so
Kiireks kontrolliks sobib küsida
$ python ... >>> import cx_Oracle >>> print cx_Oracle.version 5.1.2
Nt selline skript kirjutab tabelist t1 välja nö tulpade A ja B väärtused arvestades UTF-8 kodeeringut
$ cat skript.py import os import cx_Oracle os.environ["NLS_LANG"] = "ESTONIAN_ESTONIA.AL32UTF8" connection = cx_Oracle.connect("kasutajanimi/parool@DVK") cursor = connection.cursor() cursor.execute(""" select A, B from t1""") for column_1, column_2 in cursor: print "Values:", column_1, column_2
kus
- skript eeldab sarnase sisuga /opt/instantclient/tnsnames.ora faili olemasolu
# cat /opt/instantclient/tnsnames.ora DVK = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = oradb2a-vip.auul)(PORT = 1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = oradb2b-vip.auul)(PORT = 1521)) (LOAD_BALANCE = yes) ) (CONNECT_DATA = (SERVICE_NAME = dvk.auul) (FAILOVER_MODE = (TYPE = SELECT) (METHOD = BASIC) ) ) )
Kasulikud lisamaterjalid
- http://lucasepe.blogspot.com/2010/05/installing-python-cxoracle-module-on.html
- http://cx-oracle.sourceforge.net/html/index.html
- http://www.oracle.com/technetwork/articles/dsl/python-091105.html
SMTP
TODO
Plaintext
Skript saadab smtp serveri kaudu välja kirja
import smtplib fromaddr = "From: Priit Kask <priit@loomaaed.tartu.ee>" toaddrs = "To: Mart Kask <mart@loomaaed.tartu.ee>" msg = fromaddr + "\n" + toaddrs + "\nSubject: test" + "\nkirja sisu" server = smtplib.SMTP('192.168.1.250') server.set_debuglevel(1) server.sendmail(fromaddr, toaddrs, msg) server.quit()
MIME multipart
nn MIME multipart kirja saatmist käsitleb nt viimane näide aadressilt http://docs.python.org/library/email-examples.html
import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText me = "priit@loomaaed.tartu.ee" you = "mart@loomaaed.tartu.ee" # Create message container - the correct MIME type is multipart/alternative. msg = MIMEMultipart('alternative') msg['Subject'] = "Link" msg['From'] = me msg['To'] = you # Create the body of the message (a plain-text and an HTML version). text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.python.org" html = """\ <html> ... HTML tekst """ # Record the MIME types of both parts - text/plain and text/html. part1 = MIMEText(text, 'plain') part2 = MIMEText(html, 'html') # Attach parts into message container. # According to RFC 2046, the last part of a multipart message, in this case # the HTML message, is best and preferred. msg.attach(part1) msg.attach(part2) # Send the message via local SMTP server. s = smtplib.SMTP('smtp.loomaaed.tartu.ee') # sendmail function takes 3 arguments: sender's address, recipient's address # and message to send - here it is sent as one string. s.sendmail(me, you, msg.as_string()) s.quit()
DNS
Pythoni seest DNS kasutamiseks sobib kasutada dnspython http://www.dnspython.org/ tarkvara, paigaldamiseks Debian keskkonnas tuleb öelda
# apt-get install python-dnspython
Selline skript esitab tekstifailis toodud domeeninimedele vastavate A kirjete ip aadressid
import dns.resolver for rida in open ('hostid'): try: answers = dns.resolver.query(rida.rstrip(), 'A') for rdata in answers: print rida.rstrip() + " " + str(rdata) except dns.resolver.NXDOMAIN: print ('Domeeninimel %s puudub A kirje' % rida.rstrip())
LDAP
Pythoni seest LDAP kataloogi kasutamiseks sobib tarkvara python-ldap http://www.python-ldap.org/, paigaldamiseks Debian keskkonnas tuleb öelda
# apt-get install python-ldap
Skript LDAP kataloogist päringu tegemiseks, küsitakse kõik andmed
import ldap l = ldap.initialize('ldap://192.168.1.247') result_set = l.search_s('dc=loomaaed,dc=tartu,dc=ee',ldap.SCOPE_SUBTREE,'(objectClass=*)',['cn', 'uid', 'loginShell']) for i in result_set: print i
Tulemuseks olev result_set on loend korteežidest, viimane for-kordus esitab nende korteežide väärtused, üks real.
XMPP
# apt-get install python-pyxmpp python-pyxmpp-doc
$ python /usr/share/doc/python-pyxmpp-doc/examples/send_message.py priit@jabber.loomaaed.tartu.ee parool \ mart@jabber.loomaaed.tartu.ee subject body
Help kasutamine
>>> help() Welcome to Python 2.5! This is the online help utility. If this is your first time using Python, you should definitely check out the tutorial on the Internet at http://www.python.org/doc/tut/. Enter the name of any module, keyword, or topic to get help on writing Python programs and using Python modules. To quit this help utility and return to the interpreter, just type "quit". To get a list of available modules, keywords, or topics, type "modules", "keywords", or "topics". Each module also comes with a one-line summary of what it does; to list the modules whose summaries contain a given word such as "spam", type "modules spam". help>
Sisestades help> prompti järele huvipakkuva mooduli nime saab selle mooduli kohta teavet, nt
help> smtplib Help on module smtplib: NAME smtplib - SMTP/ESMTP client class. FILE /usr/lib/python2.5/smtplib.py MODULE DOCS http://www.python.org/doc/current/lib/module-smtplib.html DESCRIPTION This should follow RFC 821 (SMTP), RFC 1869 (ESMTP), RFC 2554 (SMTP Authentication) and RFC 2487 (Secure SMTP over TLS). ...
Programmide käivitamine shellist
Aadressil http://jimmyg.org/blog/2009/working-with-python-subprocess.html on toodud mitmeid näiteid subprocess mooduli kasutamise kohta
import subprocess pipe = subprocess.Popen(["df", "-h"], stdout=subprocess.PIPE) print pipe.communicate()[0]
Väljastatakse kahe elemendilise korteeži esimene element.
UDP sõnumi saatmine
Aadressil 192.168.10.35:514/udp töötavale syslogile sõnumi saatmiseks sobib selline järgnevus
import socket port = 514 host = "192.168.10.35" s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.sendto("test sonum\n", (host, port))
Välja TCP ühenduse tekitamine
# cat tcp-valja.py import socket # Import socket module s = socket.socket() # Create a socket object host = socket.gethostname() # Get local machine name port = 12345 # Reserve a port for your service. s.connect(('192.168.10.124', 8888)) s.send("Hello server!") f = open('/etc/fstab','rb') print 'Sending...' l = f.read(1024) while (l): print 'Sending...' s.send(l) l = f.read(1024) f.close() print "Done Sending" print s.recv(1024) s.close # Close the socket when done
Katsetamiseks sobib käivitada 192.168.10.124 arvutil nt nc
$ nc -l -p 8888 > /tmp/filename.txt
ning saata andmeid
$ ./tcp-out.py
Alamprotsesside loomine
Alamprotsesside loomise (ingl. k. to fork) teel saab käivitada paralleelselt mitmeid protsesse. Alamprotsessi loomisel moodustatakse olemasolevast protsessist koopia, ning edasi töötab arvutis kaks protsessi
- vanem (ingl .k. parent) - protsessi, milles toimus fork funktsiooni väljakutse
- laps (ingl. k. child) - fork tulemusena tekkinud uus protsessi
Põhimõtteliselt töötab alamprotsessi moodustamine selliselt, tulemusena on käivitatud töötavast programmist juurde teine eksemplar
import os def child( ): print 'Siin laps', os.getpid( ) os._exit(0) # else goes back to parent loop def parent( ): while 1: newpid = os.fork( ) if newpid == 0: child( ) else: print 'Siin vanem ', os.getpid( ), newpid if raw_input( ) == 'q': break parent( )
kus
- def parent ( ) - kirjeldab funktsiooni, mis programmi täitmisel esmalt käivitatakse
- def child ( ) - kirjeldab funktsiooni, mille täitmine kutsutakse parent funktsioonist välja
- parent funktsioonis toimub os.fork() funktsiooni väljakutse, mille tulemusena arvuti mälus on kaks samasisulist programmi, millest üks on vanem ja teine laps; nende edasi töötamisel laps puhul on rahuldatud tingimus 'if netpid == 0' ning muul juhul on tegu vanemaga
- programmi töö lõpetab while kordusest q sisestuse abil väljumine
Forkimise järel aga ei pea laps olema tingimata sama sisuga kui vanem, näiteks alltoodud skript kasutab os.execlp funktsiooni asendades lapse programmi funktsiooni argumendiks olevate väärtustele vastava tegevusega kopeerides ftp serverist faile
import os filesetid = ('bsd', 'base46.tgz', 'comp46.tgz', 'etc46.tgz', 'man46.tgz', 'misc46.tgz') for fileset in filesetid: pid = os.fork() if pid == 0: os.execlp('wget', 'wget', '-q', 'http://ftp.aso.ee/pub/OpenBSD/4.6/amd64/' + fileset) assert False, 'error starting program' else: print 'fileset: ', pid raw_input( )
Skripti töötamise ajal paistavad protsessitabelis sellised sissekanded
# ps auf USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND priit 31463 0.0 0.2 19040 2076 pts/2 S<s 06:30 0:00 -bash priit 32009 0.1 0.4 16420 3068 pts/2 S<+ 08:03 0:00 \_ python fork-dl.py priit 32010 0.0 0.2 26372 2036 pts/2 S<+ 08:03 0:00 \_ wget -q http://ftp.aso.ee/pub/OpenBSD/4.6/amd64/bsd priit 32011 0.2 0.2 26372 2032 pts/2 S<+ 08:03 0:00 \_ wget -q http://ftp.aso.ee/pub/OpenBSD/4.6/amd64/base46.tgz priit 32012 0.1 0.2 26372 2036 pts/2 S<+ 08:03 0:00 \_ wget -q http://ftp.aso.ee/pub/OpenBSD/4.6/amd64/comp46.tgz priit 32013 0.1 0.2 26372 2028 pts/2 S<+ 08:03 0:00 \_ wget -q http://ftp.aso.ee/pub/OpenBSD/4.6/amd64/etc46.tgz priit 32014 0.0 0.2 26372 2032 pts/2 S<+ 08:03 0:00 \_ wget -q http://ftp.aso.ee/pub/OpenBSD/4.6/amd64/man46.tgz priit 32015 0.0 0.2 26372 2032 pts/2 S<+ 08:03 0:00 \_ wget -q http://ftp.aso.ee/pub/OpenBSD/4.6/amd64/misc46.tgz
Lõime kasutamine
Lõimed võimaldavad sarnaselt alamprotsesside moodustamisele korraldada paralleelselt tegevusi, kuid selle erinevusega, et kõik tegevused toimuvad ühe ja sama protsessi sees. Võrreldes protsessidega on lõimedele iseloomulik, et kõik lõimed jagavad omavahel mitmeid ressursse, nt globaalseid muutujaid ja seega erinevate lõimede vahel võib olla mõnel juhtumil lihtsam korraldada andmevahetust kui erinevate protsesside vahel.
Lõime (ingl. k. thread) kasutamine toimub põhimõtteliselt selliselt
import thread def child(tid): print 'Tervist loimest nr', tid def parent( ): i = 0 while 1: i = i+1 thread.start_new(child, (i,)) if raw_input( ) == 'q': break parent( )
kus
- skript käivitab funktsiooni parent ( )
- parent ( ) seest kutsutakse välja while korduse sees thread.start_new() abil lõimena funktsioon child()
- thread.start_new() täitmise lõppu ootamata liigutakse skriptis edasi
Järgnev skript kopeerib ftp serverist faile
import thread import urllib def child(fileset): print 'Tervist loimest, kopeerin faili: ', fileset urllib.urlretrieve('http://ftp.aso.ee/pub/OpenBSD/4.6/amd64/' + fileset, fileset) filesetid = ('bsd', 'base46.tgz', 'comp46.tgz', 'etc46.tgz', 'man46.tgz', 'misc46.tgz') for fileset in filesetid: thread.start_new(child, (fileset,)) raw_input( )
kus
- raw_input( ) - kui klaviatuurilt sisestust mitte oodata, siis jõuaks programmi täitmine lõpule enne kui lõimed on lõpetanud
Tulemusena töötab kokku protsessis seitse lõime
$ ps -aeLf | grep python | grep -v grep UID PID PPID LWP C NLWP STIME TTY TIME CMD priit 1308 880 1308 0 7 15:06 pts/0 00:00:00 python loim-ftp.py priit 1308 880 1309 0 7 15:06 pts/0 00:00:00 python loim-ftp.py priit 1308 880 1310 0 7 15:06 pts/0 00:00:00 python loim-ftp.py priit 1308 880 1311 0 7 15:06 pts/0 00:00:00 python loim-ftp.py priit 1308 880 1312 0 7 15:06 pts/0 00:00:00 python loim-ftp.py priit 1308 880 1313 0 7 15:06 pts/0 00:00:00 python loim-ftp.py priit 1308 880 1314 0 7 15:06 pts/0 00:00:00 python loim-ftp.py
kust on näha, et kõigil ridadel on sama PID väärtus kuid erinevad LWP väärtused.
Käsurea argumentide kasutamine skriptis
sys.argv loend sisaldab programminime ja käsureal kasutatud argumentide väärtusi, skript
import sys for i in sys.argv: print i
väljastab käivitamisel
$ python skript.py yks kaks kolm skript.py yks kaks kolm
Standard-sisendi kasutamine skriptis
Selleks, et skript kasutaks standard-sisendi (ingl. k. stdio) sobib kasutada nt sellist konstruktsiooni
import sys next = sys.stdin.readline while 1: rida = next() if not rida: break print rida.rstrip()
Kasutamiseks sobib öelda
$ cat tekstifailinimi | python skript.py
Regulaaravaliste kasutamine
Skript esitab tekstifailist tunnusele vastavad read
import re for rida in open ('tekstifail.txt'): matchobj = re.search('muster', rida) if matchobj: print rida.rstrip()
Tühikute pealt loendi moodustamine
>>> p = re.compile(r'\s+') >>> p.split('all tcp 192.168.2.47:1433 <- 10.0.5.13:2746 ESTABLISHED:ESTABLISHED') ['all', 'tcp', '192.168.2.47:1433', '<-', '10.0.5.13:2746', 'ESTABLISHED:ESTABLISHED']
Sõne mustrile vastavuse kontrollimine
if re.search('name:', rida): print rida
Sõnes asenduse tegemine
tsooninimi=sname.replace('name: \"', )
OOP
Objekt-orienteeritud programmeerimine (OOP) tähendab vähemalt kahte asja
- mõtteviisi, mida kasutatakse ülesandega tegelemiseks
- konkreetseid keele poolt pakutavaid OOP vahendeid
class nimed: def __init__(self, domeeninimi, omanik ): self.domeeninimi = domeeninimi self.omanik = omanik self.ttl = 86400 def suurendattl(self, kordaja): self.ttl = self.ttl * kordaja # objektid moodustamine eesti = nimed(domeeninimi = 'eesti.ee', omanik = 'Calevipoeg') tartu = nimed(domeeninimi = 'tartu.ee', omanik = 'Dor Batt') # too objektidega eesti.suurendattl(2) # tulemuste esitamine print eesti.omanik print (eesti.ttl)
kus
- class nimed - kirjeldab klassi 'nimed'
- def _init__ - nn konstruktor, mis on tehniliselt tavaline funktsioon kusjuures ta täidetakse klassi põhjal instance'i moodustamisel esimesena; tavaliselt kirjeldatakse seal muutujate vaikeväärtused
- def suurendattl - tööd tegev meetod
- eesti = nimed(...) - klassidest instance'ite moodustamine
Süsteemi programmide käivitamine
Operatsioonisüsteemi programmide käivitamiseks sobib kasutada os.system
#!/usr/bin/python import os os.system("sleep 5")
Lambda funktsioon
Mõne Python funktsiooni argumendina on ettenähtud kasutada funktsiooni, nt funktsioon filter abil saab esitada ette antud loendi elementidest selliseid, millele funktsiooni rakendamine annab tõese tulemuse. Tavalisel juhul toimuks see nt nii, kirjeldame funktsiooni vaiksemviiest ning andmed loendiga loend
>>> def vaiksemviiest(x): return x < 5 >>> loend = [ 1, 2, 3, 4, 5, 6 ]
ja kasutame filter funktsiooni
>>> print filter(vaiksemviiest, loend) [1, 2, 3, 4]
Sama tulemuse saab saavutada kasutades lambda funktsiooni selliselt
>>> print filter(lambda x: x < 5, loend) [1, 2, 3, 4]
Lambda funktsiooni nimetatakse üldiselt anonüümseks funktsiooniks kuna funktsioonil puudub ilmutatud kujul nimi, ta kirjeldatakse seal, kus kasutatakase.
GeoIP teegi kasutamine
Kopeerida nt http://dev.maxmind.com/geoip/geolite aadressilt GeoLiteCity andmebaas ning paigaldada teek
# apt-get install python-geoip
Seejärel saab küsida nt sellise skriptiga ip aadressile vastava riigi ning Autonomous System'i nime
# cat riik-as.py #!/usr/bin/python import GeoIP asn_lookup = GeoIP.open('/root/geoip/GeoIPASNum.dat', GeoIP.GEOIP_MEMORY_CACHE) gi = GeoIP.open('/root/geoip/GeoLiteCity.dat',GeoIP.GEOIP_STANDARD) asn = asn_lookup.org_by_addr('10.106.101.164') gir = gi.record_by_name('10.106.101.164') print gir['country_name'] + ': ' + asn
Kasutamisel öeldakse nt
$ python riik-as.py Estonia: AS65001 Auul IX
netaddr teegi kasutamine
netaddr teegi abil saab teha kergesti erinevaid ip aadresside teisendusi, paigaldamiseks sobib öelda
# apt-get install python-netaddr
Nt sellise skripti abil saab aadressilt http://dev.maxmind.com/geoip/legacy/geolite/ jagatavast tasuta Country andmebaasist
$ cat GeoIPCountryWhois.csv "1.0.0.0","1.0.0.255","16777216","16777471","AU","Australia" "1.0.1.0","1.0.3.255","16777472","16778239","CN","China" "1.0.4.0","1.0.7.255","16778240","16779263","AU","Australia" ...
võtta välja huvipakkuva maa ip aadressid ja esitada nad Linux ipset jaoks sobivas vormis
$ cat subnet-to-cidr.py from netaddr import * for rida in open ('GeoIPCountryWhois.csv-CN'): rida = rida.rstrip() andmed = rida.split(',') subnetid = IPRange(andmed[0][1:][:-1], andmed[1][1:][:-1]) for subnet in subnetid.cidrs(): print "-A cn " + str(subnet)
Tulemuseks on
$ python subnet-to-cidr.py -A cn 1.0.1.0/24 -A cn 1.0.2.0/24 -A cn 1.0.3.0/23 -A cn 1.0.4.0/22 ...
Märkused
- Skriptist väljumine etteantud exit code'iga, nt Nagiose agentide puhul vajalik
>>> import sys >>> sys.exit(2) $ echo $? 2
Daemoni kasutamine
https://pypi.python.org/pypi/python-daemon ...
# apt-get install python-daemon
Muu hulgas paigaldatakse kaks teeki
/usr/share/pyshared/daemon/daemon.py /usr/share/pyshared/daemon/runner.py
try-except kasutamine
from daemon import DaemonContext from daemon.pidlockfile import PIDLockFile context = DaemonContext(pidfile = PIDLockFile("/var/run/mydaemon.pid")) context.open() try: retry_main_loop() except Exception, e: pass context.close()
with ja context kasutamine
Tundub, et sedasi saab kasutada kõige paindlikumalt.
DaemonRunner kasutamine
DaemonRunner kasutamine toimub nö objekt-orienteeritud viisil
$ cat skript.py import os import time from datetime import datetime from daemon import runner class App(): def __init__(self): self.stdin_path = '/dev/null' self.stdout_path = '/dev/null' self.stderr_path = '/dev/null' self.pidfile_path = '/tmp/mydaemon.pid' self.pidfile_timeout = 5 def run(self): filepath = '/tmp/currenttime.txt' dirpath = os.path.dirname(filepath) while True: if not os.path.exists(dirpath) or not os.path.isdir(dirpath): os.makedirs(dirpath) f = open(filepath, 'a') f.write(datetime.strftime(datetime.now(), '%Y-%m-%d %H:%M:%S\n')) f.close() time.sleep(10) app = App() daemon_runner = runner.DaemonRunner(app) daemon_runner.do_action()
kus
- class App() kirjeldab hädavajalikud funktsioonid, __init__ ja run
- runner.DaemonRunner kutsutakse välja näidates argumendiks klassi instance nime
- daemon_runner.do_action() vaikimisi käivitab run funktsiooni, lisaks saab ta aru stop argumendist
- tundub, et sedasi ei saa kirjedada nn context (nt umask, chroot jms)
Käivitamiseks sobib öelda
$ python sktipt.py start
Tulemusena hakkab täituma fail /tmp/currenttime.txt
Kasulikud lisamaterjalid
- https://github.com/arnaudsj/python-daemon/blob/master/daemon/runner.py
- http://nanvel.name/weblog/python-unix-daemon/
Kasulikud lisamaterjalid
- http://python-daemon.sourcearchive.com/documentation/1.5.2-2/classdaemon_1_1daemon_1_1DaemonContext.html
- http://www.python.org/dev/peps/pep-3143/
pip kasutamine
pip paigaldamiseks
# apt-get install python-pip
Tarkvara paigaldamiseks
# pip search www # pip install wwwclient
Tulemusena paigutakse failid kataloogi
/usr/local/lib/python2.7/dist-package
Paialdatud pakettide nimekirja esitamiseks
# pip freeze # pip list
pip paketis sisalduvate failide nimekirja esitamine
# pip3 show -f dnspython3
pip paketist olemasolevate versioonide küsimine
# pip3 install paketinimi==
pip paketi spetsiifilise versiooni paigaldamine
# pip3 install paketinimi==1.2.3
Virtual Python Environment builder
Virtual Python Environment builder https://pypi.python.org/pypi/virtualenv tarkvara tegeleb failisüsteemi näidatud kataloogi Python teekide paigaldamisega ning võimaldab käivitada Pyhton rakendusi nende teekide suhtes. Tehnika on sarnane chrootimisele, aga erineb selles mõttes, et UNIX protsess ei ole chroot'itud, vaid manipuleeritakse Pyhton teekide PATH'idega. virtualenv'i saab kasutada edukalt tavakasutajana shellist, WSGI jaoks läbi Apache veebiserveri ja supervisor'i deemonite haldamisel. Paigaldamiseks sobib öelda
# apt-get install virtualenv
Kasutamise muudab mugavamaks täiendavate skriptide paigaldadamine
# apt-get install virtualenvwrapper
Kasutamiseks
# mkdir /opt/lg # chown kasutaja:kasutaja /opt/lg # su - kasutaja $ mkdir conf $ cd conf
Kataloogi /opt/lg/conf alla tekitatakse alamkataloogi venv Virtual Python Environment ning automaatselt sisenetakse sinna (prompt algab sulgudes keskkonna nimega)
$ WORKON_HOME=/opt/lg/conf mkvirtualenv venv (venv)kasutaja@lg:/opt/lg/conf$
Selles promptis saab praktiliselt teha kõike nagu nö päris operatsioonisüsteemi promptis, ainult Pythoni teekide pathid on muudetud. Nt saab pip abil tarkvara paigaldada (millises failisüsteemi kataloogis seejuures asutakse ei ole oluline)
(venv)kasutaja@lg:/opt/lg/conf$ pip install paketinimi
Keskkonnas väljumiseks Ctrl-D või deactivate
(venv)kasutaja@lg:/opt/lg/conf$ deactivate kasutaja@lg:/opt/lg/conf$
Olemasolevasse keskkonda sisenemiseks tuleb öelda (. assemel sobib kasutada ka 'source' käsku)
kasutaja@lg:/opt/lg/conf$ . venv/bin/activate
Keskkonna eemaldamiseks sobib öelda
$ WORKON_HOME=/opt/lg/conf rmvirtualenv venv Removing env...
ja seejärel kustutada
$ rm -rf venv
Tundub, et praktiliselt võib ka niisama keskkonnale vastava kataloogi kustutada, eelnevalt jälgida, et protsessid sealt ei tööta ega kasuta sealt faile.
Supervisor
Supervisor http://supervisord.org/ tarkvara on alternatiivne süsteemis töötavate deemonite haldusvahend.
mod kasutamine
Vahel on tarvis sooritada mingit tegevust nö iga mingi korra järel, nt iga 500
$ cat ./mod.py #!/usr/bin/python for i in range(2000): if not i % 500: print i
$ ./mod.py 0 500 1000 1500
Automaatika kasutamine
Tööpõhimõte
Väited
- antud juhul kasutatakse automaatika serveriga suhtlemisel python teeke, python integratsioone jms
- pythonit kasutatakse Ubuntu tavapaketihaldusest ning pip pyhtoni halduse abil
Süsteemi ettevalmistamine
- töökohaarvuti Ubuntu (nt v.22.04, v.24.04)
- Python (nt v. 3.10 st Ubuntu tavapaketihaldusest)
- Microsoft Code
- git klient ja git repository ligipääs (teeb kaaslastega suhtlemise sujuvamaks)
Kasutamine
TODO
Kasulikud lisamaterjalid
- TODO
Kasulikud lisamaterjalid
- http://www.python.org/, http://docs.python.org/
- Learning Python, 4rd editon (v. 2.6 ja 3.0), Mark Lutz
- Programming Python, 3rd Mark Lutz
- Python Cookbook, 2rd edition, Alex Martelli, Anna Martelli Ravenscroft, David Ascher
- http://en.wikipedia.org/wiki/Python_(programming_language)
- Ruby
- Scapy kasutamine
- http://www.tutorialspoint.com/python/