From 8540f7ca17b029b12bee6d8bef1c3e8911d688a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Mo=C5=BEina?= Date: Wed, 2 Nov 2016 14:06:33 +0100 Subject: Text explaining modules and methods. --- .../problems/functions_and_modules/modules_sl.html | 251 +++++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 python/problems/functions_and_modules/modules_sl.html (limited to 'python/problems/functions_and_modules/modules_sl.html') diff --git a/python/problems/functions_and_modules/modules_sl.html b/python/problems/functions_and_modules/modules_sl.html new file mode 100644 index 0000000..ec414ef --- /dev/null +++ b/python/problems/functions_and_modules/modules_sl.html @@ -0,0 +1,251 @@ + + + + + + + + + + +

Kako uporabljamo module

+ +

Doslej smo spoznali le prgišče funkcij - input, + len, sqrt. V resnici pa skupaj s Pythonom dobimo + tisoče funkcij za vse mogoče reči, od pošiljanja pošte in kriptografije do + predvajanja zvoka in brskanja po datotekah .zip. Še večja gora funkcij + obstaja na spletu: karkoli si zamislite napisati, skoraj gotovo je nekdo + - če le gre za dovolj splošno reč - že potreboval kaj takšnega ter to tudi + napisal in vam dal na razpolago. Da se ne bi izgubili v gori funkcij (in + drugih reči), jih moramo nekako urediti.

+ +

Modul je zbirka funkcij (in omenjenih drugih reči). Veliko modulov dobimo + že kar ob namestitvi Pythona, druge poberemo z interneta. Da bi lahko + uporabljali funkcije iz modula, moramo modul najprej uvoziti, kar storimo + z ukazom import, ki mu sledijo imena enega ali več modulov. + S Pythonom dobimo, recimo, modul z matematičnimi funkcijami, ki se imenuje + math in ga uvozimo takole:

+ +
import math
+ +

To praviloma storimo na začetku programa. Ko je modul uvožen, kličemo + njegove funkcije. Do funkcije, ki se nahaja v modulu, pridemo tako, da + napišemo ime modula, piko, in ime funkcije.

+ +
>>> math.sqrt(2)
+1.4142135623730951
+>>> math.log(2.71828)
+0.99999932734728203
+>>> math.log10(100)
+2.0
+ +

Primer druge reči, ki je v modulu, so konstante.

+ +
>>> math.pi
+3.1415926535897931
+ +

Drug primer modula je, recimo, modul s funkcijami, ki vračajo naključna + števila (in počnejo tudi druge naključne reči), random. Ta + ima, recimo, funkcijo randint(a, b), ki vrne naključno število + med podanima vrednostima a in b (vključno z + b! Tu pravilo o tem, da b ni vključen, ne bi + imelo veliko smisla). Še dve zanimivi funkciji sta choice, + ki vrne naključno izbrani element seznama, in shuffle, ki + naključno premeša elemente seznama.

+ +
>>> import random
+>>> random.randint(10, 20)
+17
+>>> random.randint(10, 20)
+16
+>>> random.randint(10, 20)
+10
+>>> l = ["Ana", "Berta", "Cilka", "Dani", "Ema", "Fanci"]
+>>> random.choice(l)
+'Ana'
+>>> random.choice(l)
+'Dani'
+>>> random.shuffle(l)
+>>> l
+['Ana', 'Fanci', 'Dani', 'Cilka', 'Ema', 'Berta']
+ +

random.gauss(mu, sigma) vrača naključna števila iz Gaussove + distribucije s podanim poprečjem mu in varianco + sigma. Tule je pet števil iz distribucije N(10, 3):

+ +
>>> for i in range(5):
+... 	print(random.gauss(10, 3), end=" ")
+...
+8.96174816507 8.79299353551 8.75687382602 9.49106109252 8.21589651224
+ +

Poglejmo še en modul, os. Ta vsebuje goro funkcij, povezanih + z datotekami in direktoriji (podatki o datotekah, preimenovanje, brisanje), + programi, ki tečejo na računalniku in drugo. Tako recimo funkcija + os.listdir vrne seznam vseh datotek v direktoriju, katerega + ime podamo kot argument.

+ +
>>> os.listdir("/Users/janez/Dropbox/Pedagosko/P1/2014/03 seznami")
+['blagajna.py', 'palindrom.py', 'stetje.py', 'domaca', 'razpakiranje.py',
+'zapiski.html', 'fibo.py', 'seznami.py', 'zip.py']
+ +

Funkcija os.remove pobriše datoteko s podanim imenom. Če bi + želeli v direktoriju c:\d\kontrabant pobrisati vse datoteke s + končnico .pyc, bi to storili takole:

+ +
for fname in os.listdir("/Users/janez/Dropbox/Pedagosko/P1/2014/03 seznami"):
+    if fname[-4:] == ".py":
+        os.remove("/Users/janez/Dropbox/Pedagosko/P1/2014/03 seznami" + fname)
+ +

Ob tej priliki povejmo, da ima v normalnih operacijskih sistemih vsak program + (bolj učeno: proces) nek "trenutni direktorij". Kadar imena direktorija + ne začnemo z / (ali \ ali c: ali čim podobnim na Windowsih), se ime nanaša + na datoteke oz. direktorije znotraj tega, trenutnega direktorija. Kakšen je + trenutni direktorij, nam pove funkcija getcwd() (get current + working directory), spremenimo pa ga z os.chdir. Kar smo + počeli zgoraj, bi se lahko napisalo tudi + +

Vse skupaj bi bilo morda lepše, če bi predtem zamenjali trenutni direktorij.

+ +
os.chdir("/Users/janez/Dropbox/Pedagosko/P1/2014/03 seznami")
+for fname in os.listdir("."):
+    if fname[-4:] == ".py":
+        os.remove(fname)
+ +

Ko smo ravno pri Windowsih, potarnajmo še, da ima znak \ v nizih v večini + programskih jezikov poseben pomen. Danes povejmo le, da moramo, če hočemo + dobiti \, napisati \\. Se pravi, ko bomo hoteli reči "c:\Users\janez", bomo + morali napisati "c:\\Users\\janez". Na srečo lahko tudi na Windowsih že + dolgo uporabljamo sicer običajnejši /.

+ +

Če bi datoteke raje preimenovali kot brisali - recimo tako, da bi k njihovem + imenu dodali .bak, to storimo z os.rename, ki ji podamo staro + in novo ime datoteke.

+ +
for fname in os.listdir("."):
+    if fname[-4:] == ".py":
+        os.rename(fname, fname + ".bak")
+ +

Ob modulu os se lahko naučimo še nečesa zanimivega: modul + lahko vsebuje celo druge module. Tako modul os vsebuje modul + path. Modula path nam ni potrebno uvoziti, + dovolj je, da uvozimo os. Lahko pa ga uvozimo tudi takole

+ +
import os.path
+ +

Razlike pravzaprav (skoraj) ni.

+ +

Modul os.path vsebuje različne funkcije povezane z imeni + datotek in njihovimi lastnostmi. Zanimiva je, denimo, + os.path.splitext, ki ji podamo ime datoteke in vrne terko z + dvema elementoma - osnovo imena in končnico. Pri tem ni potrebno, da + datoteka v resnici obstaja.

+ +
>>> os.path.splitext("/Users/janez/datoteka.txt")
+('/Users/janez/datoteka', '.txt')
+ +

Ker vemo, da lahko terko razpakiramo v dve spremenljivki, bomo pogosto rekli + kar

+ +
>>> osnova, koncnica = os.path.splitext("/Users/janez/datoteka.txt")
+ +

Gornji programček bi se torej še bolj lepo napisalo takole.

+ +
for fname in os.listdir("."):
+    if os.path.splitext(fname)[1] == ".py":
+        os.rename(fname, fname + ".bak")
+ +

Modul os.path ima še kup zanimivih funkcij, recimo + funkcijo, ki pove, ali določena datoteka oz. direktorij obstaja + (os.path.exists), funkcije, ki povedo ali določeno ime + predstavlja datoteko (os.isfile), direktorij + (os.isdir), povezavo (os.islink) ali kaj + drugega, kar je znano na Unixu, v Windowsih pa ne.

+ +

Uvažanje v globalni imenski prostor

+ +

Kaj je "imenski prostor" vam še ne nameravam, kaj "globalni", pa še ne + morem povedati. Vseeno se lahko naučimo, kako uvažamo vanj.

+ +

Stvar je namreč jako preprosta. Morda se mi ne da stalno pisati + math.sin, math.cos, math.pi. Če bi + raje pisal le sin, cos in pi, bom + namesto z + +

import math
+ +

modul uvozil z

+ +
from math import sin, cos, pi
+ +

S tem povem dve reči. Prva: zanimajo me le tri reči, sin, + cos in pi. Ostalih, recimo sqrt, + ne potrebujem in naj jih ne uvaža. (Dejanski mehanizem je malo drugačen, + tudi sqrt je v resnici uvožen, vendar ga ne vidim, a to ni + pomembno.) Druga: nočem, da se funkcije "skrivajo" v modulu + math, hočem jih "tu", torej, hočem jih klicati, ne da bi moral + prej pisati math..

+ +

Pogosto smo leni ali, še pogosteje, ne vemo točno, katere vse funkcije + bomo potrebovali, zato rečemo kar

+ +
from math import *
+

Zvezdica pomeni "vse funkcije" in hočemo jih tu, ne v math. + Za to obliko uvoza sem vam, da nam je bilo enostavneje, pokazal, ko smo + začeli streljati s topom.

+ +

Temu načinu uvažanja se načelno izogibamo. Pogosto ga uporabljamo pri modulu + math, iz drugih modulov pa uvažamo le posamične funkcije + (from random import randint) ali pa pustimo modul kot modul + (import random).

+ +

Kako pišemo module

+ +

Napišimo program, ki bo vseboval konstanto odgovor, +ki bo imela vrednost 42, in funkcijo, ki računa Fibonaccijeva števila. + +

odgovor = 42
+
+def fibonacci(n):
+    a = b = 0
+    for i in range(n):
+        a, b = b, a+b
+    return a
+Program shranimo pod imenom fibo.py.

+ +

To je to. V drugem programu lahko rečemo + +

import fibo
+print("Odgovor je", fibo.odgovor)
+print("Deseto Fibonaccijevo število pa je", fibo.fibonacci(10))
+ +

Tudi vse ostale finte, na primer, from fibo import odgovor, + delujejo.

+ +

Modul ni nič drugega kot program, ki ga uvozimo.

+ +

Tudi vsi drugi programi, ki ste jih napisali doslej, so hkrati moduli: + lahko jih uvozite. Pazite le na tole: ko modul uvozimo, + se ta v resnici izvede, čisto tako, kot bi se izvajal program. + Vse, kar se v tem programu-modulu definira, ostane definirano in se + nahaja v modulovem imenskem prostoru. Vendar se zgodi tudi vse ostalo, + kar piše v modulu: če pri izvajanju naleti na print("Foo") + se bo ob uvozu modula izpisalo Foo. Če program-modul vsebuje klic funkcije + (in ne le definicij), se bo ta funkcija poklicala tudi ob uvozu.

+ +

Kje Python išče module? Navadno v trenutnem direktoriju, + poleg tega pa še v drugih. Na Windowsih v, recimo, + c:\Python34\lib\site-packages. + Več o tem si lahko preberete v dokumentaciji.

+ +

Tudi sicer ne bomo rinili prav globoko v module, + samo še eno stvar omenimo, da vas ne bo presenetila. + Ko boste prvič uvozili modul, se bo poleg datoteke s končnico .py + pojavila še ena, za enakim imenom, a končnico .pyc. + Python si vanjo "prevede" (pravzaprav bi smeli pisati brez narekovajev, + temu se v resnici reče prevajanje) v obliko, v kateri ga bo lahko + naslednjič hitreje uvozil. Pri manjših modulih se to ne pozna, + pri velikem številu velikih modulov pa. Če vas moti, jo lahko pobrišete; + drugič se bo pač spet pojavila ponovno.

+ + + -- cgit v1.2.1