Модули

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

23.03.2011 г.

Въпрос (1)

numbers = [1,2,3]
while True:
    number = next(numbers)
    print(number)

Въпрос (2)

squares = map(lambda x: x*x, [0,1,2,3,4])
for x in squares:
    for y in squares:
        print(x, y)

Въпрос 3

{42: x for x in [1,2,3]}

Въпрос 4

def ones():
    while True:
        yield 1

twos = (2*x for x in ones())
twos = [2*x for x in ones()]

Въпрос (5)

def print_args(a, b, *c):
    print(a)
    print(b)
    print(c)

print_args(*range(4))

Модули

Но преди това…

.pyc

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

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()	
beers.py:
import world
world.save('beers')
world.destroy()	

Атрибути

>>> world
<module 'world' from 'world.py'>
>>> world.destroy
<function destroy at 0x7f172370b958>

Области от имена

import spam
import egg
def eat():
    print("What... more?")
spam.eat()
egg.eat()
eat()

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

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

bottles = 1
def drink_bottle():
    global bottles
    bottles += 1
import beer
bottles = 5
beer.drink_bottle()
print(bottles, beer.bottles)

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

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

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

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

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

import beer

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

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

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

def eat(what):
    print(what, "was eaten.")

if __name__ == '__main__':
    eat('The world as we know it')
[vladimiroff@latitude ~]$ python3 eater.py
The world as we know it was eaten.
>>> import eater

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

Представете си, че имаме две отделни системи, в които има модул на име 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 на по-сложно име се извършва следното:

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 *

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

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

forest/pooh.py:
name = 'Pooh'
pot = 'Full of honey'
forest/piglet.py:
name = 'Piglet'
baloon = 'Red'

forest/__init__.py:

from . import pooh
from . import piglet
pot = pooh.pot
baloon = piglet.baloon

user.py:

import forest
print(forest.pooh.name)
print(forest.piglet.name)
print(forest.pot)
print(forest.baloon)

import

>>> mod = 1
>>> import mod
>>> mod
<module 'mod' from 'mod.py'>
>>> 
mod.py
import sys

>>> import mod
>>> mod.sys

import as

import sys as sysmod
print(sysmod.path)

Почти същото е като:

import sys
sysmod = sys
del sys
sysmod.path

само че ще загубим старата стойност на sys

import forest.pooh.name as pooh_name
import forest.piglet.name as piglet_name

Още разни модулни неща (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>

Още въпроси?