Опубликован: 22.12.2005 | Уровень: для всех | Доступ: платный
Лекция 2:

Основные стандартные модули Python

Поддержка цикла разработки

Модули этого раздела помогают поддерживать документацию, производить регрессионное тестирование, отлаживать и профилировать программы на Python, а также обслуживают распространение готовых программ, создавая среду для конфигурирования и установки пакетов.

В качестве иллюстрации можно предположить, что создается модуль для вычисления простых чисел по алгоритму "решето Эратосфена". Модуль будет находиться в файле Sieve.py и состоять из одной функции primes(N), которая в результате своей работы дает все простые (не имеющие натуральных делителей кроме себя и единицы) числа от 2 до N:

import sets
import math
"""Модуль для вычисления простых чисел от 2 до N """
def primes(N):
  """Возвращает все простые от 2 до N"""
  sieve = sets.Set(range(2, N))
  for i in range(2, int(math.sqrt(N)+1)):
    if i in sieve:
      sieve -= sets.Set(range(2*i, N, i))
  return sieve
Модуль pdb

Модуль pdb предоставляет функции отладчика с интерфейсом - командной строкой. Сессия отладки вышеприведенного модуля могла бы быть такой:

>>> import pdb
>>> pdb.runcall(Sieve.primes, 100)
> /home/rnd/workup/intuit-python/examples/Sieve.py(15)primes()
-> sieve = sets.Set(range(2, N))
(Pdb) l
 10     import sets
 11     import math
 12     """Модуль для вычисления простых чисел от 2 до N """
 13     def primes(N):
 14       """Возвращает все простые от 2 до N"""
 15  ->   sieve = sets.Set(range(2, N))
 16       for i in range(2, int(math.sqrt(N)+1)):
 17         if i in sieve:
 18           sieve -= sets.Set(range(2*i, N, i))
 19       return sieve
 20
(Pdb) n
> /home/rnd/workup/intuit-python/examples/Sieve.py(16)primes()
-> for i in range(2, int(math.sqrt(N)+1)):
(Pdb) n
> /home/rnd/workup/intuit-python/examples/Sieve.py(17)primes()
-> if i in sieve:
(Pdb) n
> /home/rnd/workup/intuit-python/examples/Sieve.py(18)primes()
-> sieve -= sets.Set(range(2*i, N, i))
(Pdb) n
> /home/rnd/workup/intuit-python/examples/Sieve.py(16)primes()
-> for i in range(2, int(math.sqrt(N)+1)):
(Pdb) p sieve
Set([2, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39,
41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79,
81, 83, 85, 87, 89, 91, 93, 95, 97, 99])
(Pdb) n
> /home/rnd/workup/intuit-python/examples/Sieve.py(17)primes()
-> if i in sieve:
(Pdb) n
> /home/rnd/workup/intuit-python/examples/Sieve.py(18)primes()
-> sieve -= sets.Set(range(2*i, N, i))
(Pdb) n
> /home/rnd/workup/intuit-python/examples/Sieve.py(16)primes()
-> for i in range(2, int(math.sqrt(N)+1)):
(Pdb) p sieve
Set([2, 3, 5, 7, 11, 13, 17, 19, 23, 25, 29, 31, 35, 37, 41, 43, 47, 49, 
53, 55, 59, 61, 65, 67, 71, 73, 77, 79, 83, 85, 89, 91, 95, 97])
Модуль profile

С помощью профайлера разработчики программного обеспечения могут узнать, сколько времени занимает исполнение различных функций и методов.

Продолжая пример с решетом Эратосфена, стоит посмотреть, как тратится процессорное время при вызове функции primes():

>>> profile.run("Sieve.primes(100000)")
        709 function calls in 1.320 CPU seconds

  Ordered by: standard name

  ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       1    0.010    0.010    1.320    1.320 <string>:1(?)
       1    0.140    0.140    1.310    1.310 Sieve.py:13(primes)
       1    0.000    0.000    1.320    1.320 profile:0(Sieve.primes(100000))
       0    0.000             0.000          profile:0(profiler)
      65    0.000    0.000    0.000    0.000 sets.py:119(__iter__)
     314    0.000    0.000    0.000    0.000 sets.py:292(__contains__)
      65    0.000    0.000    0.000    0.000 sets.py:339(_binary_sanity_check)
      66    0.630    0.010    0.630    0.010 sets.py:356(_update)
      66    0.000    0.000    0.630    0.010 sets.py:425(__init__)
      65    0.010    0.000    0.540    0.008 sets.py:489(__isub__)
      65    0.530    0.008    0.530    0.008 sets.py:495(difference_update)

Здесь ncalls - количество вызовов функции или метода, tottime - полное время выполнения кода функции (без времени нахождения в вызываемых функциях), percall - тоже, в пересчете на один вызов, cumtime - аккумулированное время нахождения в функции, вместе со всеми вызываемыми функциями. В последнем столбце приведено имя файла, номер строки с функцией или методом и его имя.

Примечание:

"Странные" имена, например, __iter__, __contains__ и __isub__ - имена методов, реализующих итерацию по элементам, проверку принадлежности элемента ( in ) и операцию -=. Метод __init__ - конструктор объекта (в данном случае - множества).

Модуль unittest

При разработке программного обеспечения рекомендуется применять так называемые регрессионные испытания. Для каждого модуля составляется набор тестов, по возможности таким образом, чтобы проверялись не только типичные вычисления, но и "крайние", вырожденные случаи, чтобы испытания затронули каждую ветку алгоритма хотя бы один раз. Тест для данного модуля (написанный сразу после того, как определен интерфейс модуля) находится в файле test_Sieve.py:

# file: test_Sieve.py
import Sieve, sets
import unittest

class TestSieve(unittest.TestCase):

    def setUp(self):
        pass

    def testone(self):
        primes = Sieve.primes(1)
        self.assertEqual(primes, sets.Set())

    def test100(self):
        primes = Sieve.primes(100)
        self.assert_(primes == sets.Set([2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 
                53, 59, 61, 67, 71, 73, 79, 83, 89, 97]))

if __name__ == '__main__':
    unittest.main()

Тестовый модуль состоит из определения класса, унаследованного от класса unittest.TestCase, в котором описывается подготовка к испытаниям (метод setUp ) и сами испытания -- методы, начинающиеся на test. В данном случае таких испытаний всего два: в первом испытывается случай N=1, а во втором -- N=100.

Запуск тестов производится выполнением функции unittest.main(). Вот как выглядят успешные испытания:

$ python test_Sieve.py
..
----------------------------------------------------------------------
Run 2 tests in 0.002s

OK

В процессе разработки перед каждым выпуском все модули прогоняются через регрессионные испытания, чтобы обнаружить, не были ли внесены ошибки. Однако никакие тесты в общем случае не могут гарантировать безошибочности сложной программы. При дополнении модулей тесты также могут быть дополнены, чтобы отразить изменения в проекте.

Кстати, сам Python и его стандартная библиотека имеют тесты для каждого модуля - они находятся в каталоге test в месте, где развернуты файлы поставки Python, и являются частью пакета test.

Модуль pydoc

Успех проекта зависит не только от обеспечения эффективного и качественного кода, но и от качества документации. Утилита pydoc аналогична команде man в Unix:

$ pydoc Sieve
Help on module Sieve:

NAME
    Sieve - Модуль для вычисления простых чисел от 2 до N

FILE
    Sieve.py

FUNCTIONS
    primes(N)
        Возвращает все простые от 2 до N

Эта страница помощи появилась благодаря тому, что были написаны строки документации - как ко всему модулю, так и к функции primes(N).

Стоит попробовать запустить pydoc следующей командой:

pydoc -p 8088

И направить браузер на URL http://127.0.0.1:8088/ - можно получить документацию по модулям Python в виде красивого web-сайта.

Узнать другие возможности pydoc можно, подав команду pydoc pydoc.

Пакет docutils

Этот пакет и набор утилит пока что не входит в стандартную поставку Python, однако о нем нужно знать тем, кто хочет быстро готовить документацию (руководства пользователя и т.п.) для своих модулей. Этот пакет использует специальный язык разметки (ReStructuredText), из которого потом легко получается документация в виде HTML, LaTeX и в других форматах. Текст в формате RST легко читать и в исходном виде. С этим инструментом можно познакомиться на http://docutils.sourceforge.net

Пакет distutils

Данный пакет предоставляет стандартный путь для распространения собственных Python-пакетов. Достаточно написать небольшой конфигурационный файл setup.py, использующий distutils, и файл с перечислением файлов проекта MANIFEST.in, чтобы пользователи пакета смогли его установить командой

python setup.py install

Тонкости работы с distutils можно изучить по документации.

Сергей Крупко
Сергей Крупко

Добрый день.

Я сейчас прохожу курс  повышения квалификации  - "Профессиональное веб-программирование". Мне нужно получить диплом по этому курсу. Я так полагаю нужно его оплатить чтобы получить диплом о повышении квалификации. Как мне оплатить этот курс?

 

Павел Ялганов
Павел Ялганов

Скажите экзамен тоже будет ввиде теста? или там будет какое то практическое интересное задание?

Мария Кравцова
Мария Кравцова
Россия, Сочи, РГПУ им. А.И.Герцена, 1997
Екатерина Архангельская
Екатерина Архангельская
Россия, СПбГУАП