Модули

„ Програмиране с Python“, ФМИ

Стефан Кънев & Николай Бачийски & Точо Точев & Димитър Димитров

18.03.2009г.

Елементарен проблем

world.py:


""" A module for playing with the world. """
def destroy():
    """Destroys the world."""
    print("The world was destroyed!")

def save(kind):
    """Saves a kind."""
    print("All the", kind, "were saved.")

Искаме да ползваме горните функции в много програми, а не искаме да копираме кода във всяка от тях.

Елементарно решение

women.py:

import world
world.save('women')
world.destroy()
animals.py:
import world
world.save('animals')
world.destroy()

Работи без проблеми ако трите файла са в една директория.
Чрез модули можем да използваме един и същи код много пъти (code reuse).

Атрибути

Области от имена (1)

Области от имена (2)

Ако използваме модули няма нужда да се притесняваме, че в няколко програми сме използвали едни и същи имена.

Търсене на атрибути

Модули и обхвати

Използване на модули — import

Чрез вградената фунцкия import ни дава възможност да ползваме код от външни файлове.

Ето какво се случва, ако изпълним import mod:

  1. Намира се файла, в който се намира модула
  2. Кодът се компилира до байт-код (ако е необходимо)
  3. Кодът на модула се изпълнява (дефиниции на функции, друг код)
  4. На името mod се присвоява обекта на изпълнения модул

Търсене на файла

import mod

Търси се в:

  1. текущата директория
  2. променливата на средата PYTHONPATH
  3. системни директории с модули
  4. директории, описани в .pth файлове

Всички по реда на претърсване: списъка sys.path

Модул vs. Програма

Пакети от модули

Представете си, че имаме две отделни системи, в които има модул на име game

system1/
	game.py
	<други модули>
system2/
	game.py
	<други модули>

Сега напишете система, която използва модулите game и от двете други:

import game
game.play()

Тук вече имаме малък проблем.

Пакети от модули (2)

Би било много удобно ако можехме да разделим двата модула game в отделни пакети:

import system1.game
import system2.game
system1.game.play()
system2.game.play()

Това е възможно при няколко условия:

При import на по-сложно име се извършва следното:

Пакети от модули (3)

С пакети от модули можем с едни замах да import-нем много модули:

forest/pooh.py:

name = 'Pooh'

forest/piglet.py:

name = 'Piglet'

forest/__init__.py:

from . import pooh
from . import piglet
user.py:
import forest
print(forest.pooh.name)
print(forest.piglet.name)

import

import as

import sys as sysmod
print(sysmod.path) Почти същото е като:
import sys
sysmod = sys
del sys
sysmod.path
само че ще загубим старата стойност на sys

from mod import names

Понякога е досадно да извикваме всеки път цялото име на накой обект, като universe.milkyway.earth.europe.bg.beautify()



from universe.milkyway.earth.europe.bg import beautify beautify()

Или даже:


from universe.milkyway.earth.europe.bg import beautify as b b()

from mod import *

Хубаво ли ви е така:

from mod import a,b,c,d,e,f,g,h,i,j,k,l

И на мен. Затова Python ни позволява да внесем в нашия модул всички имена от някой друг: from mod import *

Още разни модулни неща (1)

Съществува модул builtins, който съдържа всички вградени функции и други имена:
import builtins
builtins.dir = abs
print(dir(-3))

Още разни модулни неща (2)

Модулите се импортират само веднъж:
>>> import world
>>> world.save('babas')
All the babas were saved.
>>> world.save = 5
>>> import world
>>> world.save
5

Още разни модулни неща (3)

За презареждане трябва да се ползва reload():
>>> world.save
5
>>> from imp import reload
>>> reload(world)
>>> world.save
<function save at 0x015001F0>

Още въпроси?