Это старая версия документа.


Модули

Модули предлагают способ расширить программирование на Python. Вы можете создать свои модули, использовать те, которые поставляются с Python или которые написали другие. В самом Python есть сотни модулей, которые облегчают написание программ. Список модулей, поставляемых с Python, находится по адресу: http://docs.python.org/modindex.html. Некоторые модули предназначены для определённых операционных систем, но большинство из них кроссплатформенные и работают одинаково на Linux, Mac и Microsoft Windows. Для использования внешнего модуля необходимо импортировать его в программу. Один из модулей, поставляемых с Python, называется «random». Он даёт возможность генерировать псевдослучайные числа. Мы используем этот модуль в нашем первом примере.

#=======================================
# random_example.py
# Module example using the random module
#=======================================
import random
# print 14 random integers
for cntr in range(1,15):
    print random.randint(1,10)

Давайте разберём код по строкам. Первые четыре строки — это комментарии, о которых мы говорили в прошлый раз. Пятая строка говорит Python, что нужно использовать модуль «random». Мы должны явно указать Python на это.

В седьмой строке находится цикл «for», который печатает 14 случайных чисел. В строке восемь вызывается функция randint(), которая отображает случайное целое число в диапазоне от 1 до 10. Обратите внимание, что мы должны указать из какого модуля эта функция. В этом случае мы вызываем её random.randint. Зачем вообще создавать модули? Если бы все возможные функции включались непосредственно в Python, Python был бы очень большим и медленным, к тому же отладка стала бы кошмаром. Используя модули, мы можем разбить код на группы, специфичные для определённых потребностей. Если, например, вам не нужно использовать функциональность баз данных, то вам и не нужно знать, что здесь есть модуль для SQLite. Однако, когда он вам понадобится, вы его легко найдёте. Мы ещё будем использовать модули баз данных в последующих статьях.

Начав работать с Python, возможно, вы создадите свои собственные модули, чтобы использовать уже написанный код снова и снова, без необходимости повторного набора. Если вам нужно поменять что-то в этом коде, вы сможете сделать это с минимальным риском для кода в основной программе. Правда, на это есть ограничения, и мы разберёмся с этим позже. Когда мы использовали команду «import random», мы получили доступ ко всем функциям в модуле random. Если же нам нужна только функция randint(), можно привести оператор импорта к такому виду:

from random import randint

Теперь при вызове функции не надо указывать идентификатор «random.», и наш код меняется на:

from random import randint
# print 14 random integers
for cntr in range(1,15):
	print randint(1,10)

Функции

Когда мы импортировали модуль random, мы использовали функцию randint(). Функция — это блок кода, который создан для того, чтобы вызывать его в программе, обычно, более одного раза. Это упрощает работу над программой и предотвращает набор одного и того же кода снова и снова. Грубо говоря, если вам нужно написать некоторый код больше, чем 1-2 раза, стоит сделать его функцией. Хотя следующие два примера очень простые, это хорошие примеры функций. Теперь мы хотим, скажем, взять два числа, сложить их, перемножить, вычесть одно из другого, затем вывести на экран эти числа и результаты одновременно. Допустим, нам нужно сделать это три раза для трёх наборов чисел. Тогда наш пример будет выглядеть как код ниже.

#silly example
print '%d + %d = %d ' % (1,2,1+2)
print '%d * %d = %d ' % (1,2,1*2)
print '%d - %d = %d ' % (1,2,1-2)

print '\n'
print '%d + %d = %d ' % (1,4,1+4)
print '%d * %d = %d ' % (1,4,1*4)
print '%d - %d = %d ' % (1,4,1-4)

print '\n'
print '%d + %d = %d ' % (10,5,10+5)
print '%d * %d = %d ' % (10,5,10*5)
print '%d - %d = %d ' % (10,5,10-5)
print '\n'

Здесь нужно не только набрать много текста, но и непременно возникнут ошибки как при написании, так и при внесении изменений. Вместо этого мы создадим функцию, которую назовём «DoTwo». Она будет каждый раз брать два числа, проводить математические операции и выводить результат. Начнём с ключевого слова «def», которое сигнализирует о том, что мы собираемся определить функцию. После слова «def» добавим название функции и список параметров, если таковые имеются, в круглых скобках. Эту строку необходимо завершить двоеточием. Код функции набирается с отступом. Наш улучшенный простой пример (№2) показан ниже.

#silly example 2...still silly, but better
def DoTwo(num1,num2):
	print '%d + %d = %d ' % (num1,num2,num1+num2)
	print '%d * %d = %d ' % (num1,num2,num1*num2)
	print '%d - %d = %d ' % (num1,num2,num1-num2)
	print '\n'
DoTwo(1,2)
DoTwo(1,4)
DoTwo(10,5)

Как видите, здесь написано меньше кода — 8 строк вместо 12. Если нам нужно будет что-либо поменять в функции, мы сможем сделать это, не создавая проблем для нашей программы. Чтобы вызвать функцию, нужно написать её имя и параметры.

Теперь другой пример функции. Рассмотрите следующие условия.

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

'+===============================+'
'| Item 1		   X.XX |'
'| Item 2		   X.XX |'
'|------------------------------|'
'| Total		   X.XX |'
'+===============================+'

Стоимость каждой покупки и сумма должны быть в долларах и центах. Ширина вывода должна быть изменяемой, значения слева и справа — тоже. Чтобы всё сделать, нам понадобятся три функции. Первая будет выводить верхнюю и нижнюю линии, вторая будет выводить строки покупок, включая строку суммы, а третья — разделительную линию. К счастью, в Python можно это сделать очень просто. Если вы помните, мы вывели строку, умноженную на 4, и она вернула четыре копии одной и той же строки. Мы можем использовать это в своё преимущество. Чтобы распечатать наши верхнюю или нижнюю линии, мы можем взять нужную ширину в виде числа, отнять от этого числа 2 (для двоих плюсов по бокам), и использовать символы '=' между плюсами. То есть в результате если мы возьмем длину линии, например, 10, Python отнимет 2 от этого числа для плюсов по бокам, а остальные 8 использует для плюсов, и получиться вот так:

+========+

Чтобы сделать еще проще, мы будем использовать переменные замены, чтобы поставить все эти элементы в одной строку. Таким образом, наша строка в виде кода Python будет выглядеть как 'return '%s%s%s' % ('+',('=' * width-2 )),'+'). Теперь мы могли бы вывести это на экран, но мы будем использовать возвращённое ключевое слово, чтобы отправить генерируемый строку обратно в нашу вызванную линию. Назовём нашу функцию 'TopOrBottom' и код этой функции будет выглядеть вот так:

def TopOrBottom(width):
# width is total width of returned line
	return '%s%s%s' % ('+',('=' * (width-2)),'+')

Мы могли бы оставить за скобками комментарий, но приятно, чтобы иметь возможность сразу же установить, что за параметр является 'width'. Чтобы вызвать эту функцию, мы должны ввести 'print TopOrBottom(40)' или какую-либо другую длину линии. Теперь мы имеем функцию, которая позаботится о двух строках. Мы можем написать новую функцию для создания разделительной черты, используя тот же тип кода … или мы можем модифицировать только что сделанную включить выбор символов для использования плюсов в середине. Давайте сделаем это. Мы можем все еще вызвать это с помощью TopOrBottom.

def TopOrBottom(character,width):
# width is total width of returned line
# character is the character to be placed between the '+' characters
	return '%s%s%s' % ('+',(character * (width-2)),'+')

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

print TopOrBottom('=',40)

Так что теперь, мы не только позаботились о тех трёх линиях, мы сократили количество процедур, что нам нужно от 3 до 2. Таким образом, нам нужно распечатать только центральную часть.

Давайте вызовем новую функцию 'Fmt'. Передадим ей 4 значения параметра: val1– имя покупки для вывода налево leftbit – длина левого «столбца» val2 – цена покупки для вывода вправо (который должен быть «плавающим» значением) rightbit – длина правого «столбца».

Первая задача заключается в форматировании информация для правой стороны. Поскольку мы хотим, чтобы отображалось долларах и центах, мы можем использовать специальную функцию замены переменной, которая гласит: печать значения как число с плавающей точкой с n числом располагается справа от десятичной точки. Команда будет '%2.f'. Мы назначим это к переменной, названной 'part2'. Таким образом наша строка кода будет 'part2 = '%.2f' % val2'. Мы также можем использовать набор функций, встроенных в строки Python, называющиеся ljust и rjust. Ljust будет отправлять строки влево, делая отступы справа с любого символа, которого Вы хотите. Rjust делает то же самое, кроме того, что отступает на левую сторону. Теперь давайте немного уберём мусор. Используя замены мы бросаем вместе большые строки и возвращаем его в код вызова. Вот наша следующая строка.

return '%s%s%s%s' % ('| ',val1.ljust(leftbit-2,' '),part2.rjust(rightbit-2,' '),' |')

Хотя это выглядит довольно сложно на первый взгляд, давайте проанализируем код:

'%s%s%s' - место задержки.

% ( - начинает список переменных.

'| ', - Выводит левую боковую рамку (заметьте, вместе с пробелом).

val1.ljust - переменная val1 будет служить названием покупки, имя которой будет назначено Вами в вызове функции. Она будет отведена влево (о чём говорит команда ljust).

leftbit-2 - то же самое назначение, что у width-2 в предыдущей функции. В вызове функции мы задаём максимальное место для имени покупки (в данном случае 30), а width-2 отнимает 2 символа у этого числа для боковой рамки с пробелом (для красивости). Это означает, что 28 символов отведено на название покупки, и неиспользованные символы будут заменены на пробелы, чтобы у рамки была фиксированная длина.

Part2.rjust - такой же самый принцип что с val1.ljust, только здесь не название покупки, а её цена, и отводиться она не влево, а вправо. Также ей задаётся длина символов в вызове функции.

rightbit-2 - аналогично leftbit-2.

' |' - выводит правую рамку (тоже с пробелом, но слева от рамки).

Вот и всё. Теперь стоит заняться поиском ошибок. Вы можете сделать это в качестве самостоятельного упражнения. Итак… наша функция «Fmt» состоит всего из двух строчек кода, не включая определение функции и комментарии. Можно вызвать её так.

print Fmt('Item 1',30,item1,10)

И снова, мы можем назначить возвращённое значение другой строке, но можем и просто вывести его на печать. Напоминаю, что мы указываем ширину слева — 30, а справа — 10. Сумма равна 40. Это число мы и передали в функцию «TopOrBottom» раньше. Теперь запустите ваш редактор и введите код, который расположен ниже.

#pprint1.py
#Example of semi-useful functions
def TopOrBottom(character,width):
    # width is total width of returned line
    return '%s%s%s' % ('+',(character * (width-2)),'+')
def Fmt(val1,leftbit,val2,rightbit):
    # prints two values padded with spaces
    # val1 is thing to print on left, val2 is thing to print on right
    # leftbit is width of left portion, rightbit is width of right portion
    part2 = '%.2f' % val2
    return '%s%s%s%s' % ('| ',val1.ljust(leftbit-2,' '),part2.rjust(rightbit-2,' '),' |')
# Define the prices of each item
item1 = 3.00
item2 = 15.00
# Now print everything out...
print TopOrBottom('=',40)
print Fmt('Item 1',30,item1,10)
print Fmt('Item 2',30,item2,10)
print TopOrBottom('-',40)
print Fmt('Total',30,item1+item2,10)
print TopOrBottom('=',40)

Сохраните код в файл «pprint1.py» и запустите его. Должно получиться что-то похожее на текст справа ниже.

+======================================+
| Item 1			  3.00 |
| Item 2			 15.00 |
+--------------------------------------+
| Total				 18.00 |
+======================================+

Хоть этот пример и простой, он должен дать вам понять, как и зачем использовать функции. Теперь давайте немного углубимся и узнаем побольше о списках. Помните во второй статье цикла я впервые упомянул списки? Я лишь забыл вам сказать, что списки могут включать всё, даже другие списки. Давайте создадим список в нашей программе и заполним его так:

itms = [['Soda',1.45],['Candy',.75],['Bread',1.95],['Milk',2.59]]

Если нам нужно обратиться к этой пере-менной, как к обычному списку, то следует напи-сать print items[0]. Однако, в этом случае мы получим ['Soda',1.45]. Это не то, чего мы добиваемся при обычных обстоятельствах. Мы хотим обратиться к каждому элементу в этом первом списке. Тогда нужно использовать «print itms[0][0]», чтобы получить «Soda» и [0][1], чтобы получить стоимость — 1.45. Теперь у нас есть 4 покупки, и мы хотим использовать информацию о них в нашем красивом шаблоне. Всё, что нам нужно поменять, это информацию в конце программы. Сохраните последнюю версию кода как «pprint2.py», закомментируйте два определения пунктов и введите список, который вы видите сверху. Это должно выглядеть так.

#item1 = 3.00
#item2 = 15.00
itms = [['Soda',1.45],['Candy',.75],['Bread',1.95],['Milk',2.59]]

Удалите все строки, в которых вызывается Fmt(). Затем добавьте следующие (с #NEW LINE в конце) так, чтобы код стал похож на этот текст:

itms = [['Soda',1.45],['Candy',.75],['Bread',1.95],['Milk',2.59]]

print TopOrBottom('=',40)

total = 0 #NEW LINE
for cntr in range(0,4): #NEW LINE
	print Fmt(itms[cntr][0],30,itms[cntr][1],10) #NEW LINE
	total += itms[cntr][1] #NEW LINE
print TopOrBottom('-',40)
print Fmt('Total',30,total,10) #CHANGED LINE
print TopOrBottom('=',40)

Я создал переменную-счётчик для цикла, которая обходит весь список для каждого элемента. Заметьте, что я также добавил переменную «total». Делаем её равной нулю прежде, чем мы зайдём в цикл «for». Теперь, выводя на печать каждую покупку, мы прибавляем её стоимость к «total». В конце мы выводим саму «total» после разделительной линии. Сохраните вашу программу и запустите её. Вы увидите что-то, похожее на текст снизу.

+====================================+
| Soda 				1.45 |
| Candy 			0.75 |
| Bread 			1.95 |
| Milk 				2.59 |
+------------------------------------+
| Total 			6.74 |
+====================================+

Если вы хотите ещё усложнить программу, можете добaвить строку с налогом. Выводить её нужно примерно так же, как и итоговую сумму, но вместо цены поставить '(total * .086)'.

print Fmt('Tax:',30,total*.086,10)

Если вы хотите, вы можете добавить в список ещё больше наименований и посмотреть, как будет работать программа.

На этот раз хватит. На следующем занятии мы подробно изучим классы. Не скучайте!