Наши партнеры








Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

Р.Сузи. Спецкурс "Язык Python и его приложения"

Практическое занятие 2.


Занятие посвящено модулям и классам.

Код нетривиальных программ принято располагать в нескольких модулях.
Стандартные модули Python находятся (в Linux) в каталоге
/usr/lib/python*
(где на месте звездочки - версия Python, например 1.5 или 2.2)

Модуль - это обычная программа на Python, используемая из других модулей.
Модули подгружаются в Python-программу по оператору import 
или from-import. Поиск модулей производится в каталогах, указанных
в переменной sys.path:

>>> import sys
>>> print sys.path
['', '/usr/lib/python1.5/', '/usr/lib/python1.5/plat-linux-i386', 
'/usr/lib/python1.5/lib-tk', '/usr/lib/python1.5/lib-dynload', 
'/usr/lib/python1.5/site-packages']

В первую очередь поиск идет в текущем каталоге.

Наберите следующие файлы в тектовом редакторе:

********************** ПРИМЕЧАНИЕ ***************************
Для копирования содержимомго файлов удобно использовать
следующий метод:

1. Скопируйте выделенный текст в клипбоард
2. В консоли UNIX:
  - Подать команду vi  (текстовый редактор vi)
  - Нажать i для перехода в режим вставки
  - Вставить содержимое клипбоарда, нажав правую кнопку мыши
  - Нажать Esc и Z Z для выхода с сохранением
3. Применить команду 

chmod +x файл.py 

   для установки признака исполняемости
4. Запустить программу можно командой

./файл.py

************************************************************

--- A.py ---
#!/usr/bin/python

"""Пример модуля"""

def a(x):
  return "a: " + str(x)

# End of A.py

--- M.py ---
#!/usr/bin/python

"""Главный модуль"""

import A
print A.a("proba")

# End of M.py


И запустите главный модуль:

$ chmod +x M.py
$ ./M.py
a: proba

Заметьте, что в каталоге образовался новый файл: A.pyc

$ ls A.*
A.py  A.pyc

В этом файле - скомпилированный в код Python-машины модуль A.

Для следующего упражнения понадобится два соединения с UNIX-машиной.

Измените главную программу так:

#!/usr/bin/python

"""Главный модуль"""

import time
import A
from A import a

while 1:
  print A.a("proba"), a("proba2")
  time.sleep(2)
  reload(A)

# End of M.py

И запустите его на исполнение на одной консоли:

$ ./M.py
a: proba a: proba2
a: proba a: proba2

На другой консоли отредактируйте модуль A.py
следующим образом:

--- A.py ---
#!/usr/bin/python

"""Пример модуля"""

def a(x):
  return "a2: " + str(x)

# End of A.py

Вот что должно получиться:

$ ./M.py
a: proba a: proba2
a: proba a: proba2
a: proba a: proba2
a: proba a: proba2
a2: proba a: proba2
a2: proba a: proba2
a2: proba a: proba2
a2: proba a: proba2
a2: proba a: proba2

Попробуйте тоже самое со следующим главным модулем:

#!/usr/bin/python

"""Главный модуль"""

import time
import A
from A import a

while 1:
  print A.a("proba"), a("proba2")
  time.sleep(2)
  reload(A)
  from A import a

# End of M.py

Другой путь агрегации данных и операций, который хорошо дополняет
модульный подход - описание классов объектов.

Простейший класс описать очень легко:

--- C.py ---
#!/usr/bin/python

"""Пример программы с классом"""

class S:
  """ Простейший класс """
  pass

s = S()
print S
print s

# End of C.py

Запустите программу.

Немного усложним наш пример, добавив конструктор __init__()
и метод __str__():

#!/usr/bin/python

"""Пример программы с классом"""

class S:
  """ Класс посложнее """
  def __init__(self, x=0): 
    self.x = x
  def __str__(self):
    return "S(%s)" % self.x  

s = S()
print S
print s

# End of C.py

Оператор print использует __str__() для преобразования
объекта к строке. Тот же метод использует встроенная 
функция str(). Таким образом, str(s) == s.__str__().

Теперь нетривиальный пример:

--- sig_poly.py ---
#!/usr/bin/python

def m_fly(self):
  return "Я летаю."
def m_swim(self):
  return "Я плыву."
def m_sing(self):
  return "Я пою."

class Everybody:
  def i_am(self):
    return "Я %s." % self.name
  def __getattr__(self, attname):
    def cant_do(self=None, action=attname):
      return "Я не умею %s." % action
    return cant_do

class Fish(Everybody):
  name = "Рыба"
  swim = m_swim

class Mermaid(Everybody):
  name = "Русалка"
  sing = m_sing
  swim = m_swim

class Bird(Everybody):
  name = "Птица"
  fly = m_fly
  sing = m_sing

class Man(Everybody):
  name = "Человек"
  sing = m_sing

f = Fish(); r = Mermaid(); b = Bird(); m = Man()
print f.i_am(), f.swim(), f.sing(), f.fly()
print r.i_am(), r.swim(), r.sing(), r.fly()
print b.i_am(), b.swim(), b.sing(), b.fly()
print m.i_am(), m.swim(), m.sing(), m.fly()
print "Людей научили плавать."
Man.swim = m_swim    
print m.i_am(), m.swim(), m.sing(), m.fly()

# End of sig_poly.py


Дополните 
class Everybody:
следующим методом:

  def __str__(self):
    return "Я %s." % self.name

Теперь можно делать так:

print f, r, b, m

Дело в том, что метод __str__ - специальный. Его вызывает 
оператор print или функция str() для получения представления объекта в виде строки.