http://wiki.linuxformat.ru/wiki/api.php?action=feedcontributions&user=Zeggel&feedformat=atomLinuxformat - Вклад участника [ru]2024-03-28T19:37:28ZВклад участникаMediaWiki 1.19.20+dfsg-0+deb7u3http://wiki.linuxformat.ru/wiki/LXF79:PythonLXF79:Python2010-09-12T19:05:03Z<p>Zeggel: /* Регулируем выражения */</p>
<hr />
<div>{{Цикл/Python}}<br />
'''''ЧАСТЬ 5''' Мы долго изучали различные компоненты Pyhton, и теперь пришло время сделать что-то понастоящему полезное. Сегодня мы вместе с '''Сергеем Супруновым''' перейдем к одному очень важному с практической точки зрения применению языка Python – обработке текста.<br />
<br />
__TOC__<br />
<br />
Пожалуй, для языков программирования сценариев типа Perl и Python обработка строк является одним из основных применений. Выбрать статистику из log-файла, разобрать «по косточкам» пользовательский ввод, проанализировать содержащиеся в таблице dbf данные… В общем, задачи, как полезные, так и не очень, можно придумывать бесконечно.<br />
<br />
Так уж исторически сложилось, что «мы говорим: обработка текста – подразумеваем Perl, мы говорим Perl – подразумеваем: обработка текста». По крайней мере, это любят повторять бородатые администраторы. Сегодня я постараюсь показать, что и Python справляется с этим ничуть не хуже, сохраняя при этом все свои преимущества.<br />
<br />
=== Строка как объект ===<br />
<br />
Начнём с более подробного рассмотрения строки как объекта, которому присущи определённые методы. С некоторыми операциями мы уже сталкивались, рассматривая типы данных. Раньше работа со строками велась преимущественно силами модуля string. Например, разбиение строки на слова (используя в качестве разделителя пробел) выполнялось примерно так:<br />
<source lang="python"><br />
>>> import string<br />
>>> str = "Строка символов как набор слов"<br />
>>> for s in string.split(str, " "): print s<br />
...<br />
Строка<br />
символов<br />
как<br />
набор<br />
слов<br />
</source><br />
Сейчас этот модуль ещё существует, и вы вполне можете его использовать. Однако предпочтительным является использование методов строк. В этом случае каждая строка рассматривается как объект, к которому можно применять те или иные методы. Например, приведённую выше задачу лучше решать так:<br />
<source lang="python"><br />
>>> str = "Строка символов как набор слов"<br />
>>> for s in str.split(" "): print s<br />
...<br />
Строка<br />
символов<br />
как<br />
набор<br />
слов<br />
</source><br />
Как видите, намного удобнее. Кстати, вы уже поняли, как работает метод split()? Всё правильно – принимая в качестве параметра строку разделитель (в нашем случае это пробел), он возвращает список подстрок, разделённых разделителем (извините за каламбур). Сам разделитель в итоговые подстроки не входит. Мы могли вообще не указывать параметр, поскольку пробел используется по умолчанию: str.split() вернёт тот же результат.<br />
<br />
Рассмотрим ещё несколько примеров:<br />
<source lang="python"><br />
>>> a = 'just a test line'<br />
>>> a.count('t')<br />
3<br />
>>> a.center(25)<br />
' just a test line '<br />
>>> a.rjust(30)<br />
' just a test line'<br />
>>> '-'.join(a.split())<br />
'just-a-test-line'<br />
>>> a.title()<br />
'Just A Test Line'<br />
>>> a.title().swapcase()<br />
'jUST a tEST lINE'<br />
</source><br />
Ещё не забыли, как получить полный список доступных методов? Всё правильно – наша любимая функция: dir('qwe').<br />
<br />
=== Входит и выходит ===<br />
<br />
Говоря о строках, коротко остановимся на вводе данных и форматировании вывода. И с тем, и с другим мы уже сталкивались, но не вдавались в подробности.<br />
<br />
Итак, за пользовательский ввод отвечают две функции: input() и raw_input(). В качестве аргумента они принимают строку-приглашение (она может быть пустой). Отличаются тем, что первая требует форматированного ввода – строки должны заключаться в кавычки, числа без кавычек воспринимаются именно как числовые типы данных (в зависимости от формата), и т.д. Неправильный ввод, например, отсутствие кавычек в строке, будет приводить к ошибке:<br />
<source lang="python"><br />
>>> a = input("Введите число: ")<br />
Введите число: 5<br />
>>> print a<br />
5<br />
>>> a = input("Введите число: ")<br />
Введите число: число<br />
Traceback (most recent call last):<br />
File "<stdin>", line 1, in ?<br />
File "<string>", line 1<br />
число<br />
^<br />
SyntaxError: invalid syntax<br />
</source><br />
В отличие от этого, вторая функция – raw_input() – воспринимает весь ввод в «сыром» виде как обычную строку, не пытаясь разобраться в принадлежности к конкретному типу данных. Эта задача возлагается на программиста.<br />
<br />
Теперь – пара слов о форматированном выводе. Использование знакомест %s – это его зачатки. На самом деле, возможности данного механизма гораздо богаче:<br />
<source lang="python"><br />
>>> a = 0<br />
>>> b = "один"<br />
>>> c = 2.34<br />
>>> print "Значения: %d, %s, %f" % (a, b, c)<br />
Значения: 0, один, 2.340000<br />
>>> print "Три знака после запятой: %0.3f" % c<br />
Три знака после запятой: 2.340<br />
>>> print "Выравнивание вправо: %20s" % b<br />
Выравнивание вправо: один<br />
</source><br />
Можно также использовать так называемый «словарный» синтаксис. В качестве примера рассмотрим небольшой сценарий, анализирующий учётные записи пользователей:<br />
<source lang="python"><br />
#!/usr/bin/Python<br />
fd = open('/etc/passwd', 'r')<br />
line = 'none'<br />
user = {}<br />
while line != '':<br />
line = fd.readline()<br />
if line != '' and line[0] != '#':<br />
tmp = line.split(':')<br />
user['login'] = tmp[0]<br />
user['uid'] = tmp[2]<br />
user['homedir'] = tmp[5]<br />
print "| %(login)-5s | %(uid)5s | %(homedir)-14s |" % user<br />
fd.close()<br />
</source><br />
Как видите, можно создавать именованные знакоместа вида %(key)s, где key – ключ словаря, который передаётся оператору print. Есть один интересный приём – вы всегда можете воспользоваться функцией vars(), которая вернёт словарь инициированных в данный момент переменных. То есть к переменной qwe вы можете обратиться и так: vars()['qwe']. Как следствие, вставить значение переменной qwe в вывод оператора print можно таким образом: print "%(qwe)s" % vars().<br />
<br />
{{Шаблон:Врезка|<br />
Заголовок=Некоторые описатели|<br />
Содержание=\A – начало строки<br />
<br />
\Z – конец строки<br />
<br />
\b – граница слова<br />
<br />
\d – любая цифра<br />
<br />
\s – пробельный символ<br />
<br />
\w – цифра или буква|<br />
Ширина=150px}}<br />
<br />
Знак «минус» перед числом, указывающим ширину текстового поля, означает выравнивание по левому краю (по умолчанию используется выравнивание вправо).<br />
<br />
Результат работы приведённого выше сценария будет выглядеть примерно так:<br />
serg$ ./py3.py<br />
| root | 0 | /root |<br />
| www | 80 | /nonexistent |<br />
| ftp | 21 | /home/ftp |<br />
| oops | 5002 | /nonexistent |<br />
| dspam | 8080 | /var/db/dspam |<br />
Развивая наш сценарий, можно добавить «шапку» таблицы, и т.д. Оставлю это вам в качестве упражнения.<br />
<br />
=== Регулируем выражения ===<br />
<br />
Безусловно, никакие методы строк не сравнятся по своей мощи с регулярными выражениями. В языке Python за работу с ними отвечает модуль re (когда-то это был самостоятельный модуль, сейчас – просто «обёртка» к более мощному модулю sre).<br />
<br />
Говоря простым языком, регулярное выражение (РВ) – это специальная строка, описывающая группу строк, имеющих определённый формат. По сути, РВ – это шаблон, которому может соответствовать несколько различных строк. Например, выражение «[a-z]» описывает строки, состоящие из одной строчной буквы латинского алфавита. Специальные символы, использующиеся в регулярных выражениях, можно разделить на три группы: описатели, квантификаторы и символы группировки.<br />
<br />
Описатели – это выражения, описывающие определённый набор символов, которые могут им соответствовать. Например, «[0-9]» описывает любую цифру, «\s» – любой пробельный символ, «.» – любой символ. Просто символ, не принадлежащий специальным или экранированный обратным слэшем (например, «m», «\[») описывает сам себя.<br />
<br />
Символы группировки – круглые скобки – позволяют объединить несколько описателей в группу, которая будет рассматриваться как единое целое.<br />
<br />
Наконец, квантификаторы задают число повторений символов, соответствующих описателю или группе, после которых он задан. Например, «.*» означает любое (в том числе, нулевое) количество любых символов, «\d+» требует наличия как минимум одной цифры, выражению «([a-z][0-9]){2,4}» будет соответствовать строка, в которой группа из буквы и цифры повторяется от двух до четырёх раз – f5e3, o2o2o2o2.<br />
<br />
{{Шаблон:Врезка|<br />
Заголовок=Не все так просто|<br />
Содержание=Стоит отметить, что вполне рядовая на первый взгляд задача поиска адресов e-mail на самом деле очень и очень сложна. Стандарт RFC822, определяющий формат адреса электронной почты, предусматривает произвольную глубину вложенности комментариев (которые заключаются в круглые скобки) – подобные конструкции регулярным выражениям просто не по зубам. Полный код регулярного выражения, ограниченного одним-единственным уровнем вложенности комментариев, содержит 4724 символа! Подробности можно найти в замечательной книге Дж. Фридла «Регулярные выражения. Библиотека программиста», выпущенной издательством O'Reilly и переведенной на русский язык издательством «Питер».|<br />
Ширина=300px}}<br />
<br />
Нужно помнить об одном свойстве квантификаторов, именуемом «жадностью» – каждый квантификатор стремится захватить как можно больше символов, соответствующих описателю. Своим же «коллегам», стоящим после них, они оставляют минимум, необходимый для того, чтобы строка считалась соответствующей выражению. Например, выражение «.+.+» требует, чтобы в строке было две последовательности любых символов, как минимум с одним символом в каждой. Строка «qwerty» будет ему соответствовать, при этом первый «+» поглотит все символы, кроме последней буквы, которую необходимо отдать второму квантификатору.<br />
<br />
Жадность квантификатора можно поубавить, поставив после него символ «?». Например, «.+?.+?» будет вести себя уже по-другому – первый «+» заберёт себе один символ (по принципу, «а мне больше и не надо»), а всё остальное придётся «кушать» второму квантификатору.<br />
<br />
Казалось бы, не всё ли равно, кто сколько символов захватит? Главное ведь чтобы результат был одинаковый? Если нам нужно просто определить соответствие, то, конечно, разницы никакой. Но если мы используем группировку для последующей обработки фрагментов (см. пример ниже), то о «жадности» забывать нельзя.<br />
<br />
Однако хватит теории (о регулярных выражениях много и хорошо написано в различных книгах, статьях и на man-страницах). Вернёмся к модулю re.<br />
<br />
Наиболее типичный способ его использования – создание объекта-шаблона с помощью метода re.compile() с последующим его применением к конкретным строкам с помощью методов re.match(), re.search(), re.sub() и т.д. Методы match() и search() отличаются тем, что первый требует соответствия РВ с начала строки, а второй проверяет наличие подходящего фрагмента в любом месте строки:<br />
<source lang="python"><br />
>>> a = re.compile('\d+')<br />
>>> print a.search('qwe123') or "Нет соответствия"<br />
<_sre.SRE_Match object at 0x81bbd78><br />
>>> print a.match('qwe123') or "Нет соответствия"<br />
Нет соответствия<br />
>>> print a.match('123qwe') or "Нет соответствия"<br />
<_sre.SRE_Match object at 0x81bbd78><br />
</source><br />
Как видите, в случае соответствия как match(), так и search() возвращают объект класса SRE_Match. Получить фрагмент, удовлетворяющий РВ, можно с помощью метода group() этого объекта:<br />
<source lang="python"><br />
>>> print a.search('qwe123qwe').group()<br />
123<br />
</source><br />
В данном примере мы «вырезали» число из строки (чему при желании можно найти достаточно много практических применений).<br />
<br />
Метод sub(текст_замены, строка) выполняет замену соответствующих шаблону фрагментов заданной строкой:<br />
<source lang="python"><br />
>>> a = re.compile('\d+')<br />
>>> print a.sub('несколько', 'Стоит 50 рублей')<br />
Стоит несколько рублей<br />
</source><br />
Пример использования ещё одного полезного метода – findall() – вы найдёте в рассматриваемом ниже сценарии. Ну а в том, как работает split(), думаю, разберётесь сами.<br />
<br />
{{Шаблон:Врезка|<br />
Заголовок=Некоторые квантификаторы|<br />
Содержание=<nowiki>* – любое количество фрагментов</nowiki><br />
<br />
+ – один и более фрагментов<br />
<br />
? – ноль или один фрагмент<br />
<br />
{m,n} – не меньше m и не больше n|<br />
Ширина=150px}}<br />
<br />
В качестве примера решим задачу – выбрать из некоторого текста все адреса электронной почты (только не подумайте, что я помогаю спамерам – скальпель тоже иногда может пользу приносить). Чтобы не сильно усложнять алгоритм, будем считать, что фрагмент строки является электронным адресом, если он соответствует следующим условиям:<br />
* обязательное наличие символа «@» внутри фрагмента;<br />
* до «@» может стоять любое число латинских букв, цифр и символов «точка»;<br />
* после «@» должно находиться не менее двух групп латинских букв, цифр и дефисов, разделённых точками; причём последняя такая группа может содержать от двух до четырёх букв (другие символы не допускаются).<br />
* к регистру символов придираться не будем.<br />
Пример «правильного» фрагмента: Vasya.Pupkin@gdeto-tam.D12.info. Записать наши требования можно с помощью такого выражения:<br />
<source lang="python"><br />
([\w.]+@([\w-]+\.)+[a-z]{2,4})\W<br />
</source><br />
Завершающий определитель \W нужен для того, чтобы после последней группы обязательно стоял не цифро-буквенный символ (в противном случае qwe@qwe.qwerty будет соответствовать РВ, т.к. квантификатор возьмёт себе необходимые 4 символа, а остальное просто не будет приниматься во внимание). Нужный же нам адрес будет форми роваться в первой группе (внешние скобки).<br />
<br />
Внимательные читатели, думаю, уже заметили, что нашему шаблону будет соответствовать и такой «адрес»: ...@-----.-.ru. Небольшим усложнением нашего «фильтра» эту проблему можно решить – попробуйте на досуге.<br />
<br />
Базовая версия нашего сценария выглядит следующим образом:<br />
<source lang="python"><br />
#!/usr/bin/Python<br />
# -*- coding: koi8-r -*-<br />
import re<br />
def getmail(text):<br />
filter = re.compile(r'([\w.]+@([\w-]+\.)+[a-z]{2,4})\W', re.I)<br />
for i in filter.findall(text):<br />
print i[0]<br />
<br />
example = '''\<br />
Этот текст служит для проверки работы функции getmail.<br />
Он должен нормально распознавать такие адреса как vasya@mail.ru, Vasya.Pupkin@gde-to.tam.D12.info, u_12@_test.me и 12.34@56-78.90.ua.<br />
Адреса вида @mail.ru, mail@mail и qwe@domain.qwerty и qwe@ma.ru123 должны игнорироваться.<br />
К сожалению, здесь не решена проблема адресов вида: ...@---.--ru.<br />
В принципе, исправить это не сложно.<br />
'''<br />
getmail(example)<br />
</source><br />
Результат его работы:<br />
serg$ ./getmail.py<br />
vasya@mail.ru<br />
Vasya.Pupkin@gde-to.tam.D12.info<br />
u_12@_test.me<br />
12.34@56-78.90.ua<br />
...@---.--.ru<br />
Вторым параметром метода compile() задаются флаги, в частности, флаг re.I (re.IGNORECASE) отключает проверку регистра символов. Дополнительных пояснений, думаю, не требуется. Замечу лишь, что findall() возвращает в кортеже все найденные группы в порядке обнаружения первой скобки. Таким образом, первым элементом и будет искомый адрес электронной почты. Ещё обратите внимание на то, что перед строкой регулярного выражения стоит буква «r». Она говорит о том, что последующую строку следует рассматривать как «сырую», то есть не обрабатывать специальные символы, экранированные обратным слэшем.<br />
<br />
Что ж, большая часть нашего пути позади. Осталось рассмотреть последний крупный вопрос: разработку приложений с графическим интерфейсом, чем в следующий раз и займёмся.</div>Zeggelhttp://wiki.linuxformat.ru/wiki/LXF77:PythonLXF77:Python2010-09-11T15:33:06Z<p>Zeggel: /* Модули */</p>
<hr />
<div>{{цикл/Python}}<br />
''Часть 3. Итак, познакомившись с типами данных, доступных в языке Python, мы, под чутким руководством '''Сергея Супрунова''' морально готовы приступить к более серьёзным вещам. На сегодня программа-минимум – разобраться с модулями и научиться писать свои функции.''<br />
<br />
==Модули==<br />
<br />
Начнем со стандартных модулей. Стандартными их называют потому, что они, как правило, уже включены в вашу поставку Python (будь то Linux, FreeBSD или даже Windows) и не требуют дополнительной инсталляции. Как вы видели в конце прошлого урока, модуль подключается оператором '''import'''. В качестве параметров вы можете указать любое количество модулей. Также допускается любое число операторов '''import''' в любой точке вашей программы.<br />
<br />
Для чего же нужны модули? Чуть позже, когда мы напишем свою функцию, вы увидите, что с помощью модуля очень легко реализуется концепция повторного использования кода. Пока же модули интересны нам как способ расширения возможностей вашей программы. С их помощью вы подключаете уже написанные кем-то наборы функций и методов, которые сможете использовать почти так же, как если бы они были встроенными (такими, как рассмотренная нами ранее '''float()''').<br />
<br />
Начнем с модуля '''sys'''. В нем определен ряд переменных, содержащих информацию об операционной системе, дескрипторы стандартных потоков ввода, вывода и ошибок ('''stdin''', '''stdout''' и '''stderr''' соответственно), и так далее. рассмотрим небольшой пример:<br />
<br />
<source lang="python"><br />
>>> import sys<br />
>>> print sys.arch, sys.platform<br />
i386 linux2<br />
>>> print sys.version<br />
2.4.1 (#1, Sep 13 2005, 00:39:20)<br />
[GCC 4.0.2 20050901 (prerelease) (SUSE Linux)]<br />
>>> print sys.maxint<br />
2147483647<br />
</source><br />
<br />
Как видите, чтобы получить доступ к определённым в модуле переменным (впрочем, это относится и к остальным объектам), перед их именем следует указать имя модуля. Это оберегает от конфликта имён, когда объявленная вами переменная или функция имеет такое же имя, как и определенная в модуле. то есть каждый модуль имеет свое пространство имен, доступ к которому осуществляется по имени модуля. Если имя модуля слишком неудобно для работы, вы можете указать для него псевдоним после ключевого слова '''as''' (например, '''import SimpleXMLRPCServer as rpc'''), и в дальнейшем использовать это упрощённое имя. Впрочем, иногда удобнее (а порой и необходимо), что-бы имена, определенные в модуле, были импортированы непосредственно в пространство имён основной программы. Для этого предусмотрена несколько иная конструкция:<br />
<br />
<source lang="python"><br />
>>> from sys import *<br />
>>> print platform<br />
linux2<br />
</source><br />
<br />
Теперь можно обращаться к объектам модуля непосредственно, но будьте осторожны – вы потеряете все определённые вами переменные и функции, имена которых совпадут с именами определенных в модуле.<br />
<br />
{{Врезка|right|<br />
|Заголовок=ПОЛЕЗНЫЙ СОВЕТ<br />
|Содержание=<br />
Когда вы работаете в интерактивном терминале, к вашим услугам всегда функция help(). Используйте её, когда вам понадобится подсказка по той или иной функции или модулю. Не забывайте заключать в кавычки её аргумент – ведь вы передаёте имя функции, а не ее саму:<br />
'''help('dir'), help('sys')'''.<br />
|Ширина=250px}}<br />
<br />
Символ «звездочка» в операторе '''from - import''' означает, что должно быть импортировано всё, что определено в модуле. Вы также можете перечислить только то, что желаете сделать доступным в вашей программе (например, '''from sys import version''').<br />
<br />
Ещё одна важнейшая переменная модуля sys – список '''sys.argv''', в который в момент запуска Python-программы помещаются аргументы, переданные в командной строке. Пример использования этого списка вы увидите далее в данной статье.<br />
<br />
==Модуль os==<br />
<br />
Пожалуй, самый популярный модуль Python – это '''os'''. Он предоставляет вам ряд функций, позволяющих взаимодействовать с операционной системой: '''chroot()''', '''mkdir()''', '''setuid()''' и так далее. Названия, думаю, говорят сами за себя. а как посмотреть полный список функций, доступных в модуле, я надеюсь, вы ещё помните с прошлого урока: '''dir(os)'''.<br />
<br />
Для работы с файловой системой практически незаменим подмодуль этого модуля – '''os.path'''. С его помощью вы можете определять типы файлов, установленные для них права доступа, и тому подобное. Нам ещё доведётся поработать с ним на практике. <br />
<br />
==Прочие модули==<br />
<br />
Вообще, в стандартную поставку Python входит несколько десятков наиболее полезных модулей. Найти их можно в каталоге '''/usr/lib/python''' (на некоторых системах путь может быть иным, например, '''/usr/local/lib/python'''). Если быть точнее, то Python ищет свои модули в каталогах, список которых возвращает переменная '''sys.path'''.<br />
<br />
Обращайте внимание на файлы с расширением '''py''' ('''pyc''' и '''pyo''' – это байт-код модулей, который используется для экономии ресурсов, поскольку при обращении к модулю повторная компиляция не требуется). Названия большинства из них говорят сами за себя, к тому же вы можете открыть любой модуль, чтобы ознакомиться с его кодом и, как правило, очень подробными комментариями. С некоторыми из них мы обязательно столкнёмся в дальнейшем.<br />
<br />
==Функции==<br />
<br />
Со встроенными функциями вы уже знакомы. Но что делать, если возможностей, заложенных в интерпретатор или стандартные модули, вам недостаточно? Всё просто – напишите собственную функцию!<br />
<br />
Пользовательская функция определяется оператором '''def''' (от '''define''' – определять). В качестве параметра указывается имя функции (оно должно быть уникально в пределах пространства имён основной программы), а в скобках перечисляются её формальные аргументы. Далее ставится двоеточие (как и в случае любых блочных операторов, таких как '''if''' или '''for'''), и на последующих строках, имеющих отступ, вводится код функции. Впрочем, когда речь идёт о Python, несколько строк кода способны сказать больше, чем пол-страницы текста на естественном языке. Чтобы лучше во всем разобраться, рассмотрим один пример (файл назовем '''abbr.py'''):<br />
<br />
<source lang="python"><br />
#!/usr/bin/python<br />
# -*- coding: utf-8 -*-<br />
"""<br />
Программа обслуживает небольшой словарь сокращений, используя anydbm<br />
"""<br />
import sys, anydbm as db<br />
dictfile = 'dict.dbm'<br />
def openDictionary(dbmfile=dictfile):<br />
""" Открыть словарь """<br />
global dictionary<br />
try:<br />
dictionary = db.open(dbmfile, 'c')<br />
except:<br />
raise 'Ошибка открытия файла'<br />
def getMeaning(abbr):<br />
""" Поиск расшифровки """<br />
try:<br />
<br />
return dictionary[abbr]<br />
except:<br />
return '[не определено]'<br />
def addMeaning(abbr, meaning):<br />
""" Добавить сокращение """<br />
dictionary[abbr] = meaning<br />
def delMeaning(abbr):<br />
""" Удалить сокращение """<br />
try:<br />
del dictionary[abbr]<br />
except:<br />
pass<br />
if __name__ == "__main__":<br />
openDictionary()<br />
try:<br />
command = sys.argv[1]<br />
if command == '-a':<br />
addMeaning(sys.argv[2], sys.argv[3])<br />
elif command == '-d':<br />
delMeaning(sys.argv[2])<br />
else:<br />
abbr = sys.argv[1]<br />
print abbr + ' = ' + getMeaning(abbr)<br />
except:<br />
print """\<br />
Неверные аргументы. Допустимый синтаксис:<br />
abbr.py <ABBR> - расшифровать сокращение<br />
abbr.py -a <ABBR> <MEANING> - добавить расшифровку<br />
abbr.py -d <ABBR> - удалить сокращение<br />
"""<br />
else:<br />
openDictionary()<br />
</source><br />
<br />
Эта программа реализует простейший консольный словарь сокращений. Только не забудьте сделать файл исполняемым ('''chmod u+x abbr.py'''). Поддерживаются три операции (информацию об этом вы получите, если попытаетесь вызвать сценарий с неправильными аргументами):<br />
#'''abbr.py <ABBR>''' – возвращает из словаря расшифровку сокращения <ABBR>;<br />
#'''abbr.py -a <ABBR>'' <MEANING>''' – добавляет в словарь расшифровку сокращения. В силу особенностей словарного типа данных в Python, эта же команда изменяет расшифровку для уже существующей аббревиатуры;<br />
#'''abbr.py -d <ABBR>''' – удаляет из словаря запись для указанного сокращения.<br />
<br />
Обратите внимание на вторую строку – здесь указывается кодировка исходного текста (подробности см. на странице http://www.python.org/peps/pep-0263.html). Если вы используете не UTF-8, то укажите в этой строке свою кодировку (например, koi8-r).<br />
<br />
Строки, обрамлённые утроенными кавычками, в данном случае можно рассматривать как многострочные комментарии.<br />
<br />
Оператор '''global''' в функции '''openDictionary()''' делает переменную '''dictionary''' доступной за пределами функции. В противном случае её действие распространялось бы только на эту функцию. Ещё один интересный момент – то, как описан формальный аргумент функции. В данном случае мы задаем для переменной значение по умолчанию. Если в дальнейшем при вызове функции вы не передадите в неё аргумент, будет использовано значение переменной '''dictfile'''.<br />
<br />
Несколько слов нужно сказать о самом модуле '''anydbm'''. С его помощью Python выполняет поиск доступного dbm-пакета в текущей системе (вам не нужно об этом беспокоиться). Данные в файле '''DBM''' организованы по словарному принципу (ключ – значение), поэтому данный файл может быть естественным образом сопоставлен с переменной типа «словарь». Все дальнейшие операции с данными словаря для программиста выглядят как обычные, а dbm-модуль позаботится о том, чтобы все данные оказались сохранены в файл. Собственно говоря, '''dbm'''-файл вы можете рассматривать как словарь, содержимое которого не теряется между запусками программы. также обратите внимание, что при подключении этого модуля мы используем псевдоним.<br />
<br />
Итак, в функции '''openDictionary()''' мы открываем файл '''dict.dbm''' (второй параметр – ''''c'''' – даёт указание создать такой файл, если его ещё нет) и сопоставляем его со словарём '''dictionary'''. Конструкция «'''try – except'''» служит для обработки ошибок. В блок '''try''' мы помещаем потенциально опасные операции (которые могут завершиться с ошибкой), а блок '''except''' содержит код, который будет выполнен в случае возникновения ошибки в блоке '''try'''. Оператор raise генерирует сообщение об ошибке и прерывает выполнение программы.<br />
<br />
Далее описаны три функции, реализующие заявленную выше функциональность. Пожалуй, в пояснении нуждается здесь только оператор pass в функции '''delMeaning()''': это пустой оператор, который ничего не делает – если нужного ключа в словаре нет, то и удалять нечего.<br />
<br />
Ну и в конце сценария, в секции оператора '''if''', вы можете увидеть пример обработки аргументов командной строки.<br />
<br />
Конечно, этот учебный пример не лишён недостатков: невозможно сделать несколько записей, имеющих одинаковую аббревиатуру, работа чувствительна к регистру символов (введя запись для «UDP», вы не сможете получить значение по ключу «udp»), и т.д. Однако сейчас нам важен не функционал, а собственно языковые конструкции.<br />
<br />
==Возвращаясь к модулям==<br />
<br />
Итак, мы написали функцию, которая может оказаться крайне полезной в других программах. Как бы было хорошо, если бы оказалось возможным поместить её в модуль! А ведь нет ничего проще – она уже в модуле. Да-да! Вы можете просто подключить написанную выше программу в качестве модуля (одним из операторов, '''import''' или '''from''' – '''import''') и спокойно использовать определённые в ней переменные и функции!<br />
<br />
В этом заключается одно из преимуществ Python по сравнению с его «прямым конкурентом» - языком Perl. В Perl вам пришлось бы специально оформлять вашу программу как модуль (как минимум, потребуется оператор '''package'''). В Python концепция повторного использования кода заложена в основу синтаксиса и не требует от вас совершенно никаких усилий. <br />
<br />
Рассмотрим пример:<br />
<br />
<source lang="python"><br />
#!/usr/bin/python<br />
# -*- coding: utf-8 -*-<br />
<br />
import abbr<br />
abbr.delMeaning('UDP')<br />
print abbr.getMeaning('IP')<br />
</source><br />
<br />
Как видите, вам достаточно импортировать '''py'''-программу (расширение не указывается), и вы можете в полной мере воспользоваться всем созданным ранее. Единственное, этот файл должен быть доступен для поиска (самый простой вариант – поместить его в текущий каталог).<br />
<br />
Обратите внимание, что в момент импортирования переменная '''__name__''' в подключаемом модуле будет иметь значение, совпадающее с именем модуля. Поэтому в данном случае вместо секции '''if''' сценария '''abbr.py''' будет выполнена секция '''else'''. Подобный оператор '''if – else''' присутствует практически в каждой программе на языке Python и позволяет использовать ее и как модуль, и как самостоятельный сценарий (в последнем случае, как нетрудно догадаться, переменная '''__name__''' будет иметь значение '''"__main__"''').<br />
<br />
Итак, вы уже в состоянии разрабатывать довольно серьёзные и полезные программы. Однако не научившись работать с классами, вы не познаете всю мощь Python. В следующий раз мы заполним и этот пробел.</div>Zeggelhttp://wiki.linuxformat.ru/wiki/LXF77:PythonLXF77:Python2010-09-11T15:21:17Z<p>Zeggel: /* Модули */</p>
<hr />
<div>{{цикл/Python}}<br />
''Часть 3. Итак, познакомившись с типами данных, доступных в языке Python, мы, под чутким руководством '''Сергея Супрунова''' морально готовы приступить к более серьёзным вещам. На сегодня программа-минимум – разобраться с модулями и научиться писать свои функции.''<br />
<br />
==Модули==<br />
<br />
Начнем со стандартных модулей. Стандартными их называют потому, что они, как правило, уже включены в вашу поставку Python (будь то Linux, FreeBSD или даже Windows) и не требуют дополнительной инсталляции. Как вы видели в конце прошлого урока, модуль подключается оператором '''import'''. В качестве параметров вы можете указать любое количество модулей. Также допускается любое число операторов '''import''' в любой точке вашей программы.<br />
<br />
Для чего же нужны модули? Чуть позже, когда мы напишем свою функцию, вы увидите, что с помощью модуля очень легко реализуется концепция повторного использования кода. Пока же модули интересны нам как способ расширения возможностей вашей программы. С их помощью вы подключаете уже написанные кем-то наборы функций и методов, которые сможете использовать почти так же, как если бы они были встроенными (такими, как рассмотренная нами ранее '''float()''').<br />
<br />
Начнем с модуля '''sys'''. В нем определен ряд переменных, содержащих информацию об операционной системе, дескрипторы стандартных потоков ввода, вывода и ошибок ('''stdin''', '''stdout''' и '''stderr''' соответственно), и так далее. рассмотрим небольшой пример:<br />
<br />
<source lang="python"><br />
>>> import sys<br />
>>> print sys.arch, sys.platform<br />
i386 linux2<br />
>>> print sys.version<br />
2.4.1 (#1, Sep 13 2005, 00:39:20)<br />
[GCC 4.0.2 20050901 (prerelease) (SUSE Linux)]<br />
>>> print sys.maxint<br />
2147483647<br />
</source><br />
<br />
Как видите, чтобы получить доступ к определённым в модуле переменным (впрочем, это относится и к остальным объектам), перед их именем следует указать имя модуля. Это оберегает от конфликта имён, когда объявленная вами переменная или функция имеет такое же имя, как и определенная в модуле. то есть каждый модуль имеет свое пространство имен, доступ к которому осуществляется по имени модуля. Если имя модуля слишком неудобно для работы, вы можете указать для него псевдоним после ключевого слова '''as''' (например, '''import SimpleXMLRPCServer as rpc'''), и в дальнейшем использовать это упрощённое имя. Впрочем, иногда удобнее (а порой и необходимо), что-бы имена, определенные в модуле, были импортированы непосредственно в пространство имён основной программы. Для этого предусмотрена несколько иная конструкция:<br />
<br />
<source lang="python"><br />
>>> from sys import *<br />
>>> print platform<br />
linux2<br />
</source><br />
<br />
Теперь можно обращаться к объектам модуля непосредственно, но будьте осторожны – вы потеряете все определённые вами переменные и функции, имена которых совпадут с именами определенных в модуле.<br />
<br />
{{Врезка|right|<br />
|Заголовок=ПОЛЕЗНЫЙ СОВЕТ<br />
|Содержание=<br />
Когда вы работаете в интерактивном терминале, к вашим услугам всегда функция help(). Используйте её, когда вам понадобится подсказка по той или иной функции или модулю. Не забывайте заключать в кавычки её аргумент – ведь вы передаёте имя функции, а не ее саму:<br />
'''help('dir'), help('sys')'''.<br />
|Ширина=250px}}<br />
<br />
Символ «звездочка» в операторе '''from - import''' означает, что должно быть импортировано всё, что определено в модуле. Вы также можете перечислить только то, что желаете сделать доступным в вашей про грамме (например, '''from sys import version''').<br />
<br />
Ещё одна важнейшая переменная модуля sys – список '''sys.argv''', в который в момент запуска Python-программы помещаются аргументы, переданные в командной строке. Пример использования этого списка вы увидите далее в данной статье.<br />
<br />
==Модуль os==<br />
<br />
Пожалуй, самый популярный модуль Python – это '''os'''. Он предоставляет вам ряд функций, позволяющих взаимодействовать с операционной системой: '''chroot()''', '''mkdir()''', '''setuid()''' и так далее. Названия, думаю, говорят сами за себя. а как посмотреть полный список функций, доступных в модуле, я надеюсь, вы ещё помните с прошлого урока: '''dir(os)'''.<br />
<br />
Для работы с файловой системой практически незаменим подмодуль этого модуля – '''os.path'''. С его помощью вы можете определять типы файлов, установленные для них права доступа, и тому подобное. Нам ещё доведётся поработать с ним на практике. <br />
<br />
==Прочие модули==<br />
<br />
Вообще, в стандартную поставку Python входит несколько десятков наиболее полезных модулей. Найти их можно в каталоге '''/usr/lib/python''' (на некоторых системах путь может быть иным, например, '''/usr/local/lib/python'''). Если быть точнее, то Python ищет свои модули в каталогах, список которых возвращает переменная '''sys.path'''.<br />
<br />
Обращайте внимание на файлы с расширением '''py''' ('''pyc''' и '''pyo''' – это байт-код модулей, который используется для экономии ресурсов, поскольку при обращении к модулю повторная компиляция не требуется). Названия большинства из них говорят сами за себя, к тому же вы можете открыть любой модуль, чтобы ознакомиться с его кодом и, как правило, очень подробными комментариями. С некоторыми из них мы обязательно столкнёмся в дальнейшем.<br />
<br />
==Функции==<br />
<br />
Со встроенными функциями вы уже знакомы. Но что делать, если возможностей, заложенных в интерпретатор или стандартные модули, вам недостаточно? Всё просто – напишите собственную функцию!<br />
<br />
Пользовательская функция определяется оператором '''def''' (от '''define''' – определять). В качестве параметра указывается имя функции (оно должно быть уникально в пределах пространства имён основной программы), а в скобках перечисляются её формальные аргументы. Далее ставится двоеточие (как и в случае любых блочных операторов, таких как '''if''' или '''for'''), и на последующих строках, имеющих отступ, вводится код функции. Впрочем, когда речь идёт о Python, несколько строк кода способны сказать больше, чем пол-страницы текста на естественном языке. Чтобы лучше во всем разобраться, рассмотрим один пример (файл назовем '''abbr.py'''):<br />
<br />
<source lang="python"><br />
#!/usr/bin/python<br />
# -*- coding: utf-8 -*-<br />
"""<br />
Программа обслуживает небольшой словарь сокращений, используя anydbm<br />
"""<br />
import sys, anydbm as db<br />
dictfile = 'dict.dbm'<br />
def openDictionary(dbmfile=dictfile):<br />
""" Открыть словарь """<br />
global dictionary<br />
try:<br />
dictionary = db.open(dbmfile, 'c')<br />
except:<br />
raise 'Ошибка открытия файла'<br />
def getMeaning(abbr):<br />
""" Поиск расшифровки """<br />
try:<br />
<br />
return dictionary[abbr]<br />
except:<br />
return '[не определено]'<br />
def addMeaning(abbr, meaning):<br />
""" Добавить сокращение """<br />
dictionary[abbr] = meaning<br />
def delMeaning(abbr):<br />
""" Удалить сокращение """<br />
try:<br />
del dictionary[abbr]<br />
except:<br />
pass<br />
if __name__ == "__main__":<br />
openDictionary()<br />
try:<br />
command = sys.argv[1]<br />
if command == '-a':<br />
addMeaning(sys.argv[2], sys.argv[3])<br />
elif command == '-d':<br />
delMeaning(sys.argv[2])<br />
else:<br />
abbr = sys.argv[1]<br />
print abbr + ' = ' + getMeaning(abbr)<br />
except:<br />
print """\<br />
Неверные аргументы. Допустимый синтаксис:<br />
abbr.py <ABBR> - расшифровать сокращение<br />
abbr.py -a <ABBR> <MEANING> - добавить расшифровку<br />
abbr.py -d <ABBR> - удалить сокращение<br />
"""<br />
else:<br />
openDictionary()<br />
</source><br />
<br />
Эта программа реализует простейший консольный словарь сокращений. Только не забудьте сделать файл исполняемым ('''chmod u+x abbr.py'''). Поддерживаются три операции (информацию об этом вы получите, если попытаетесь вызвать сценарий с неправильными аргументами):<br />
#'''abbr.py <ABBR>''' – возвращает из словаря расшифровку сокращения <ABBR>;<br />
#'''abbr.py -a <ABBR>'' <MEANING>''' – добавляет в словарь расшифровку сокращения. В силу особенностей словарного типа данных в Python, эта же команда изменяет расшифровку для уже существующей аббревиатуры;<br />
#'''abbr.py -d <ABBR>''' – удаляет из словаря запись для указанного сокращения.<br />
<br />
Обратите внимание на вторую строку – здесь указывается кодировка исходного текста (подробности см. на странице http://www.python.org/peps/pep-0263.html). Если вы используете не UTF-8, то укажите в этой строке свою кодировку (например, koi8-r).<br />
<br />
Строки, обрамлённые утроенными кавычками, в данном случае можно рассматривать как многострочные комментарии.<br />
<br />
Оператор '''global''' в функции '''openDictionary()''' делает переменную '''dictionary''' доступной за пределами функции. В противном случае её действие распространялось бы только на эту функцию. Ещё один интересный момент – то, как описан формальный аргумент функции. В данном случае мы задаем для переменной значение по умолчанию. Если в дальнейшем при вызове функции вы не передадите в неё аргумент, будет использовано значение переменной '''dictfile'''.<br />
<br />
Несколько слов нужно сказать о самом модуле '''anydbm'''. С его помощью Python выполняет поиск доступного dbm-пакета в текущей системе (вам не нужно об этом беспокоиться). Данные в файле '''DBM''' организованы по словарному принципу (ключ – значение), поэтому данный файл может быть естественным образом сопоставлен с переменной типа «словарь». Все дальнейшие операции с данными словаря для программиста выглядят как обычные, а dbm-модуль позаботится о том, чтобы все данные оказались сохранены в файл. Собственно говоря, '''dbm'''-файл вы можете рассматривать как словарь, содержимое которого не теряется между запусками программы. также обратите внимание, что при подключении этого модуля мы используем псевдоним.<br />
<br />
Итак, в функции '''openDictionary()''' мы открываем файл '''dict.dbm''' (второй параметр – ''''c'''' – даёт указание создать такой файл, если его ещё нет) и сопоставляем его со словарём '''dictionary'''. Конструкция «'''try – except'''» служит для обработки ошибок. В блок '''try''' мы помещаем потенциально опасные операции (которые могут завершиться с ошибкой), а блок '''except''' содержит код, который будет выполнен в случае возникновения ошибки в блоке '''try'''. Оператор raise генерирует сообщение об ошибке и прерывает выполнение программы.<br />
<br />
Далее описаны три функции, реализующие заявленную выше функциональность. Пожалуй, в пояснении нуждается здесь только оператор pass в функции '''delMeaning()''': это пустой оператор, который ничего не делает – если нужного ключа в словаре нет, то и удалять нечего.<br />
<br />
Ну и в конце сценария, в секции оператора '''if''', вы можете увидеть пример обработки аргументов командной строки.<br />
<br />
Конечно, этот учебный пример не лишён недостатков: невозможно сделать несколько записей, имеющих одинаковую аббревиатуру, работа чувствительна к регистру символов (введя запись для «UDP», вы не сможете получить значение по ключу «udp»), и т.д. Однако сейчас нам важен не функционал, а собственно языковые конструкции.<br />
<br />
==Возвращаясь к модулям==<br />
<br />
Итак, мы написали функцию, которая может оказаться крайне полезной в других программах. Как бы было хорошо, если бы оказалось возможным поместить её в модуль! А ведь нет ничего проще – она уже в модуле. Да-да! Вы можете просто подключить написанную выше программу в качестве модуля (одним из операторов, '''import''' или '''from''' – '''import''') и спокойно использовать определённые в ней переменные и функции!<br />
<br />
В этом заключается одно из преимуществ Python по сравнению с его «прямым конкурентом» - языком Perl. В Perl вам пришлось бы специально оформлять вашу программу как модуль (как минимум, потребуется оператор '''package'''). В Python концепция повторного использования кода заложена в основу синтаксиса и не требует от вас совершенно никаких усилий. <br />
<br />
Рассмотрим пример:<br />
<br />
<source lang="python"><br />
#!/usr/bin/python<br />
# -*- coding: utf-8 -*-<br />
<br />
import abbr<br />
abbr.delMeaning('UDP')<br />
print abbr.getMeaning('IP')<br />
</source><br />
<br />
Как видите, вам достаточно импортировать '''py'''-программу (расширение не указывается), и вы можете в полной мере воспользоваться всем созданным ранее. Единственное, этот файл должен быть доступен для поиска (самый простой вариант – поместить его в текущий каталог).<br />
<br />
Обратите внимание, что в момент импортирования переменная '''__name__''' в подключаемом модуле будет иметь значение, совпадающее с именем модуля. Поэтому в данном случае вместо секции '''if''' сценария '''abbr.py''' будет выполнена секция '''else'''. Подобный оператор '''if – else''' присутствует практически в каждой программе на языке Python и позволяет использовать ее и как модуль, и как самостоятельный сценарий (в последнем случае, как нетрудно догадаться, переменная '''__name__''' будет иметь значение '''"__main__"''').<br />
<br />
Итак, вы уже в состоянии разрабатывать довольно серьёзные и полезные программы. Однако не научившись работать с классами, вы не познаете всю мощь Python. В следующий раз мы заполним и этот пробел.</div>Zeggelhttp://wiki.linuxformat.ru/wiki/LXF76:PythonLXF76:Python2010-09-11T10:02:01Z<p>Zeggel: /* Функции и модули */</p>
<hr />
<div>{{цикл/Python}}<br />
''Часть 2. Возможность выводить строку на экран и делить целые числа — огромный шаг вперед по сравнению с началом прошлого века. Но в наши дни от языка программирования требуется несколько большее, так что сегодня мы продолжаем осваивать Python вместе с '''Сергеем Супруновым'''.''<br />
<br />
== Подробнее о типах данных ==<br />
Как мы увидели на прошлом уроке, Python различает строки, целые числа и числа с плавающей запятой. Естественно, на этом его возможности не заканчиваются. Сегодня мы подробнее остановимся на оставшихся типах данных,<br />
чтобы в дальнейшем знать, с чем мы имеем дело. Начнем с последовательностей — списков, кортежей и строк.<br />
<br />
Список — это набор переменных различных типов, упорядоченный<br />
по мере добавления новых элементов. Доступ к элементу осуществляется по его порядковому номеру в последовательности (индексу). Если<br />
проводить аналогию с другими языками программирования, то этот<br />
тип данных наиболее близок к массивам.<br />
<br />
Задается список с помощью квадратных скобок, в которых элементы перечислены через запятую: [0, 1, 'два', 3.0, «четыре»]. Причем в<br />
отличие, скажем, от языка Pascal, вы вполне можете смешивать в<br />
одном списке данные разных типов. Индекс элемента, который вы<br />
хотите получить, задается также в квадратных скобках:<br />
<source lang="python"><br />
>>> a = [0, 1, 'two', 3.0]<br />
>>> print a[1]<br />
1<br />
</source><br />
Как видите, первому элементу списка соответствует индекс 0.<br />
Специального синтаксиса для аналога многомерных массивов не предусмотрено, но вы вполне можете «конструировать» их с помощью<br />
вложенных списков, когда элементом списка является другой список:<br />
<source lang="python"><br />
>>> a = [[1,2,3],[4,5,6]]<br />
>>> a[0]<br />
[1, 2, 3]<br />
>>> a[0][0]<br />
1<br />
>>> a[0][0] = 1234<br />
>>> a<br />
[[1234, 2, 3], [4, 5, 6]]<br />
</source><br />
Для изменения списка существует ряд методов (почти все элементы в Python являются объектами классов, о чем мы поговорим в<br />
одном из следующих уроков; к терминологии же начнем привыкать<br />
уже сейчас). Например, append() позволяет добавлять новые элементы в конец списка:<br />
<source lang="python"><br />
>>> a = []<br />
>>> a.append('q')<br />
>>> a.append(123)<br />
>>> a.append(a)<br />
>>> print a<br />
['q', 123, [...]]<br />
>>> print a[2]<br />
['q', 123, [...]]<br />
>>> print a[2][2][2][2][0]<br />
q<br />
</source><br />
Интересно, не правда ли? Тут мы столкнулись со специальным<br />
типом данных — Ellipsis (отображается как троеточие). Он «зацикливает» последовательность саму на себя (обратите внимание, оператор print a[2] дал точно такой же результат, как и print a), в итоге<br />
получается своего рода бесконечная последовательность. Обычно<br />
используется при обработке многомерных матриц.<br />
<br />
Рассмотрим еще несколько часто используемых методов:<br />
<source lang="python"><br />
>>> a = [1,2]<br />
>>> a.insert(0,5)<br />
>>> a<br />
[5, 1, 2]<br />
>>> a.remove(1)<br />
>>> a<br />
[5, 2]<br />
>>> a.extend(a)<br />
>>> a<br />
[5, 2, 5, 2]<br />
>>> a.pop()<br />
2<br />
>>> a<br />
[5, 2, 5]<br />
</source><br />
Разберемся, что делает этот код. Метод insert() вставляет элемент, значение которого задано во втором аргументе, начиная с<br />
позиции, заданной первым (в примере вставляем число 5 в начало<br />
списка). С помощью remove() вы можете удалить элемент по значению (если в списке несколько элементов с одним значением, удаляется первый из них). Метод extend() расширяет список заданной<br />
последовательностью (заметьте, как это отличается от append()), ну<br />
и pop() «выталкивает» из списка последний элемент. Удалить элемент по индексу можно оператором del, который справляется с<br />
любыми переменными: del a[1].<br />
<br />
Помимо этого, вы можете использовать методы sort() и<br />
reverse(). Оставим их вам для самостоятельного изучения.<br />
<br />
Для работы со списками в Python существует непревзойденный<br />
по гибкости механизм — так называемые срезы. Например, операция<br />
ar[2:5] возвратит список, содержащий элементы списка ar начиная с<br />
третьего (нумерация — с нуля!) и до шестого (исключительно).<br />
Пропуск того или иного индекса означает «с начала» или «до конца»,<br />
отрицательный индекс — «с конца списка». А с помощью ar[1:8:2]<br />
будут выбраны только четные элементы (каждый второй) из диапазона 1-7. Внимательно рассмотрите приведенные ниже примеры, поэкспериментируйте сами, и вам все станет понятно:<br />
<source lang="python"><br />
>>> a = [0,1,2,3,4,5,6,7,8,9]<br />
>>> a[3:5]<br />
[3, 4]<br />
>>> a[4:], a[:2]<br />
([4, 5, 6, 7, 8, 9], [0, 1])<br />
>>> a[-2:]<br />
[8, 9]<br />
>>> a[:]<br />
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]<br />
>>> a[1:9:3]<br />
[1, 4, 7]<br />
>>> a[::2]<br />
[0, 2, 4, 6, 8]<br />
</source><br />
Следует также сказать про так называемые списковые включения — специальные синтаксические конструкции, позволяющие генерировать список на базе другого:<br />
<source lang="python"><br />
>>> a = [b**2 for b in [1,2,3,4,5] if b > 2]<br />
>>> print a<br />
[9, 16, 25]<br />
</source><br />
Оператор «**» — это возведение в степень. Секция if спискового<br />
включения может быть опущена (в ней задается фильтрующее условие). Вместо явного указания списка (после in) вы, естественно,<br />
можете использовать и переменную, содержащую последовательность. Поэкспериментируйте со списковыми включениями — с их<br />
помощью можно достигать удивительных результатов.<br />
<br />
Кортеж — это неизменяемый список. Элементы в нем упорядочены по индексам, обращаться вы можете к ним так же, как и в списке,<br />
но методы, изменяющие кортеж, отсутствуют. Содержимое кортежа<br />
записывается в круглых скобках — tuple = (1, 2, «three»). Если<br />
вам нужно задать кортеж из одного элемента, поставьте после него<br />
запятую — ('5',).<br />
<br />
Замечу, что операции среза применимы и к кортежам (поскольку<br />
сам кортеж при этом не изменяется, а просто создается новая переменная, тоже кортеж, на его основе).<br />
<br />
Кортежи работают быстрее списков, поэтому, если вы не планируете изменять последовательность, то лучше использовать именно их.<br />
<br />
Вы можете складывать списки со списками или кортежи с кортежами — результат будет содержать элементы последовательностей-"слагаемых", причем обратите внимание, что порядок элементов<br />
всегда строго сохраняется:<br />
<source lang="python"><br />
>>> b = [3,4,5]<br />
>>> c = [1,2]<br />
>>> d = b + c + [9,8,7]<br />
>>> print d<br />
[3, 4, 5, 1, 2, 9, 8, 7]<br />
>>> d = [9,8,7] + c + b<br />
>>> print d<br />
[9, 8, 7, 1, 2, 3, 4, 5]<br />
>>> (1,2) + (3,4)<br />
(1, 2, 3, 4)<br />
</source><br />
Теперь самое время познакомиться с циклом for. Он позволяет<br />
проходить по каждому элементу последовательности, выполняя те<br />
или иные действия:<br />
<source lang="python"><br />
>>> a = [1,2,3,4,5]<br />
>>> for i in a:<br />
... print i * 2,<br />
...<br />
2 4 6 8 10<br />
</source><br />
Про отступы, думаю, вы помните. Запятая после операнда в операторе print отменяет перевод строки, благодаря чему выводимые<br />
значения располагаются на одной строке. Для организации привычного многим цикла «от X до Y» используется функция range(X, Y),<br />
генерирующая нужную последовательность:<br />
<source lang="python"><br />
>>> for i in range(3, 8):<br />
... print i,<br />
...<br />
3 4 5 6 7<br />
</source><br />
Как видите, последний индекс диапазона в результирующую последовательность, как и в случае со срезами, не включается.<br />
Постарайтесь не забывать об этой особенности, и ошибок в ваших<br />
программах будет немного меньше.<br />
<br />
Еще один тип последовательности — строка. При некотором допущении она может рассматриваться как кортеж символов (в том плане,<br />
что не позволяет выполнять изменение отдельных элементов «на<br />
месте»). Строка допускает операции среза, ее можно использовать в<br />
цикле for для прохода по каждой букве, и так далее.<br />
<br />
Помимо скалярных типов данных и последовательностей, Python<br />
поддерживает так называемые словари. Словарь — это набор пар<br />
«ключ — значение» (в Perl это называется хэшем, можно встретить и<br />
термин «ассоциативный массив»). Ключ должен быть уникален в<br />
пределах словаря (именно по нему выполняется поиск нужного элемента), и в отличие от рассмотренных выше последовательностей,<br />
порядок элементов в словаре не определен. Синтаксис и основные<br />
операции, которые вы можете выполнять над словарями, продемонстрированы в примере:<br />
<source lang="python"><br />
>>> dict = {<br />
... 'ru': 'Russia',<br />
... 'uk': 'United Kingdom',<br />
... }<br />
>>> print dict<br />
{'ru': 'Russia', 'uk': 'United Kingdom'}<br />
>>> dict.pop('uk')<br />
'United Kingdom'<br />
>>> print dict<br />
{'ru': 'Russia'}<br />
>>> dict['us'] = 'USA'<br />
>>> print dict<br />
{'ru': 'Russia', 'us': 'USA'}<br />
>>> print dict['ru']<br />
Russia<br />
>>> dict.keys()<br />
['ru', 'us']<br />
>>> dict.values()<br />
['Russia', 'USA']<br />
>>> dict.items()<br />
[('ru', 'Russia'), ('us', 'USA')]<br />
</source><br />
Запись присвоения переменной dict выполнена на нескольких<br />
строках для удобства представления (внутри фигурных скобок вы<br />
можете переносить строки и устанавливать любые отступы; аналогично можно поступать и со списками и кортежами). Но вы вполне<br />
можете записывать все в одной строке. Обращение к элементу словаря по ключу выполняется так же, как вы выбор элемента списка по<br />
индексу (с той разницей, что ключ не обязан быть целым числом).<br />
Если присвоить значение несуществующему элементу, то он добавится в словарь. Последние три метода, показанные в примере, позволяют получить соответствующие списки (ключей, значений и кортежей<br />
«ключ-значение»), которые могут быть использованы, например, для<br />
обработки словаря в цикле:<br />
<source lang="python"><br />
>>> arkeys = dict.keys()<br />
>>> arkeys.sort()<br />
>>> for domain in arkeys:<br />
... print "%s = %s" % (domain, dict[domain])<br />
...<br />
ru = Russia<br />
us = USA<br />
</source><br />
Кстати, переменные, значением которых заполняются знакоместа<br />
%s при выводе текста, если таковых две и больше, должны передаваться как кортеж, то есть в круглых скобках. Может использоваться<br />
и особый «словарный» синтаксис, использование которого будет<br />
продемонстрировано в одном из дальнейших примеров.<br />
<br />
== Функции и модули ==<br />
Чтобы завершить разговор о типах данных, нужно несколько слов<br />
сказать о функциях и модулях. Функция позволяет использовать<br />
один и тот же фрагмент кода в разных частях программы. Различают<br />
встроенные функции (которые «зашиты» в интерпретатор) и пользовательские. О вторых речь пойдет в следующем уроке, а сейчас<br />
коротко остановимся на встроенных.<br />
<br />
В первой статье цикла мы уже встречались с функцией float(),<br />
которая преобразует целое число или строку, переданные ей в качестве аргумента, в число с плавающей запятой. Как вы видели, вызов<br />
функции происходит по имени, а в скобках передаются аргументы,<br />
над которыми функция выполняет действия. Функция может не иметь<br />
аргументов, однако указывать скобки после ее имени необходимо.<br />
Результат своей работы функция возвращает основной программе<br />
(причем вызов функции трактуется в выражениях именно как это возвращаемое значение; например, в выражении sum = z + float(b) к<br />
переменной z добавится результат, возвращенный функцией, а не<br />
сама функция). Функция может и не возвращать значения явно — в<br />
этом случае возвращается результат специального типа None.<br />
<br />
Вернемся к типам данных. Полный список поддерживаемых<br />
типов можно получить с помощью следующего кода (не пугайтесь,<br />
ниже я все объясню):<br />
<source lang="python"><br />
>>> import types<br />
>>> for t in [t for t in dir(types) if t[0:2] != '__']:<br />
... print t<br />
</source><br />
Первой строкой мы подключаем один из системных модулей -<br />
types. Модуль — это программа на Python, содержащая функции,<br />
переменные, классы и т. д., которые вы можете в дальнейшем<br />
использовать в своих сценариях. Подробнее о них разговор у нас<br />
пойдет в следующий раз. Пока достаточно знать, что здесь мы подгружаем модуль types и получаем доступ к его функциям, служащим<br />
для преобразования типов. Их полный список выводит функция dir(),<br />
ну а про списковые включения вы уже знаете. Поясню только фрагмент if — с его помощью мы исключаем из вывода специальные функции и переменные, которые начинаются двумя символами подчеркивания (здесь мы применяем операцию среза к строке t).<br />
<br />
В результате выполнения этого кода вы получите список из 35<br />
функций преобразования, соответствующих типам Python. Можно<br />
увидеть, что и функции, и классы являются допустимыми типами<br />
данных, что позволяет присваивать их переменным: например, вы<br />
можете записать mydirfunc = dir, и в дальнейшем mydirfunc можно<br />
будет использовать точно так же, как и функцию dir: print<br />
mydirfunc(types).<br />
<br />
Типов данных существует достаточно много, но для начала работы с Python достаточно тех, что были описаны выше.<br />
<br />
Подведем итог. Сегодня мы не написали ничего полезного, но<br />
заложили фундамент для дальнейшей работы.</div>Zeggelhttp://wiki.linuxformat.ru/wiki/LXF76:PythonLXF76:Python2010-09-11T09:53:33Z<p>Zeggel: /* Подробнее о типах данных */</p>
<hr />
<div>{{цикл/Python}}<br />
''Часть 2. Возможность выводить строку на экран и делить целые числа — огромный шаг вперед по сравнению с началом прошлого века. Но в наши дни от языка программирования требуется несколько большее, так что сегодня мы продолжаем осваивать Python вместе с '''Сергеем Супруновым'''.''<br />
<br />
== Подробнее о типах данных ==<br />
Как мы увидели на прошлом уроке, Python различает строки, целые числа и числа с плавающей запятой. Естественно, на этом его возможности не заканчиваются. Сегодня мы подробнее остановимся на оставшихся типах данных,<br />
чтобы в дальнейшем знать, с чем мы имеем дело. Начнем с последовательностей — списков, кортежей и строк.<br />
<br />
Список — это набор переменных различных типов, упорядоченный<br />
по мере добавления новых элементов. Доступ к элементу осуществляется по его порядковому номеру в последовательности (индексу). Если<br />
проводить аналогию с другими языками программирования, то этот<br />
тип данных наиболее близок к массивам.<br />
<br />
Задается список с помощью квадратных скобок, в которых элементы перечислены через запятую: [0, 1, 'два', 3.0, «четыре»]. Причем в<br />
отличие, скажем, от языка Pascal, вы вполне можете смешивать в<br />
одном списке данные разных типов. Индекс элемента, который вы<br />
хотите получить, задается также в квадратных скобках:<br />
<source lang="python"><br />
>>> a = [0, 1, 'two', 3.0]<br />
>>> print a[1]<br />
1<br />
</source><br />
Как видите, первому элементу списка соответствует индекс 0.<br />
Специального синтаксиса для аналога многомерных массивов не предусмотрено, но вы вполне можете «конструировать» их с помощью<br />
вложенных списков, когда элементом списка является другой список:<br />
<source lang="python"><br />
>>> a = [[1,2,3],[4,5,6]]<br />
>>> a[0]<br />
[1, 2, 3]<br />
>>> a[0][0]<br />
1<br />
>>> a[0][0] = 1234<br />
>>> a<br />
[[1234, 2, 3], [4, 5, 6]]<br />
</source><br />
Для изменения списка существует ряд методов (почти все элементы в Python являются объектами классов, о чем мы поговорим в<br />
одном из следующих уроков; к терминологии же начнем привыкать<br />
уже сейчас). Например, append() позволяет добавлять новые элементы в конец списка:<br />
<source lang="python"><br />
>>> a = []<br />
>>> a.append('q')<br />
>>> a.append(123)<br />
>>> a.append(a)<br />
>>> print a<br />
['q', 123, [...]]<br />
>>> print a[2]<br />
['q', 123, [...]]<br />
>>> print a[2][2][2][2][0]<br />
q<br />
</source><br />
Интересно, не правда ли? Тут мы столкнулись со специальным<br />
типом данных — Ellipsis (отображается как троеточие). Он «зацикливает» последовательность саму на себя (обратите внимание, оператор print a[2] дал точно такой же результат, как и print a), в итоге<br />
получается своего рода бесконечная последовательность. Обычно<br />
используется при обработке многомерных матриц.<br />
<br />
Рассмотрим еще несколько часто используемых методов:<br />
<source lang="python"><br />
>>> a = [1,2]<br />
>>> a.insert(0,5)<br />
>>> a<br />
[5, 1, 2]<br />
>>> a.remove(1)<br />
>>> a<br />
[5, 2]<br />
>>> a.extend(a)<br />
>>> a<br />
[5, 2, 5, 2]<br />
>>> a.pop()<br />
2<br />
>>> a<br />
[5, 2, 5]<br />
</source><br />
Разберемся, что делает этот код. Метод insert() вставляет элемент, значение которого задано во втором аргументе, начиная с<br />
позиции, заданной первым (в примере вставляем число 5 в начало<br />
списка). С помощью remove() вы можете удалить элемент по значению (если в списке несколько элементов с одним значением, удаляется первый из них). Метод extend() расширяет список заданной<br />
последовательностью (заметьте, как это отличается от append()), ну<br />
и pop() «выталкивает» из списка последний элемент. Удалить элемент по индексу можно оператором del, который справляется с<br />
любыми переменными: del a[1].<br />
<br />
Помимо этого, вы можете использовать методы sort() и<br />
reverse(). Оставим их вам для самостоятельного изучения.<br />
<br />
Для работы со списками в Python существует непревзойденный<br />
по гибкости механизм — так называемые срезы. Например, операция<br />
ar[2:5] возвратит список, содержащий элементы списка ar начиная с<br />
третьего (нумерация — с нуля!) и до шестого (исключительно).<br />
Пропуск того или иного индекса означает «с начала» или «до конца»,<br />
отрицательный индекс — «с конца списка». А с помощью ar[1:8:2]<br />
будут выбраны только четные элементы (каждый второй) из диапазона 1-7. Внимательно рассмотрите приведенные ниже примеры, поэкспериментируйте сами, и вам все станет понятно:<br />
<source lang="python"><br />
>>> a = [0,1,2,3,4,5,6,7,8,9]<br />
>>> a[3:5]<br />
[3, 4]<br />
>>> a[4:], a[:2]<br />
([4, 5, 6, 7, 8, 9], [0, 1])<br />
>>> a[-2:]<br />
[8, 9]<br />
>>> a[:]<br />
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]<br />
>>> a[1:9:3]<br />
[1, 4, 7]<br />
>>> a[::2]<br />
[0, 2, 4, 6, 8]<br />
</source><br />
Следует также сказать про так называемые списковые включения — специальные синтаксические конструкции, позволяющие генерировать список на базе другого:<br />
<source lang="python"><br />
>>> a = [b**2 for b in [1,2,3,4,5] if b > 2]<br />
>>> print a<br />
[9, 16, 25]<br />
</source><br />
Оператор «**» — это возведение в степень. Секция if спискового<br />
включения может быть опущена (в ней задается фильтрующее условие). Вместо явного указания списка (после in) вы, естественно,<br />
можете использовать и переменную, содержащую последовательность. Поэкспериментируйте со списковыми включениями — с их<br />
помощью можно достигать удивительных результатов.<br />
<br />
Кортеж — это неизменяемый список. Элементы в нем упорядочены по индексам, обращаться вы можете к ним так же, как и в списке,<br />
но методы, изменяющие кортеж, отсутствуют. Содержимое кортежа<br />
записывается в круглых скобках — tuple = (1, 2, «three»). Если<br />
вам нужно задать кортеж из одного элемента, поставьте после него<br />
запятую — ('5',).<br />
<br />
Замечу, что операции среза применимы и к кортежам (поскольку<br />
сам кортеж при этом не изменяется, а просто создается новая переменная, тоже кортеж, на его основе).<br />
<br />
Кортежи работают быстрее списков, поэтому, если вы не планируете изменять последовательность, то лучше использовать именно их.<br />
<br />
Вы можете складывать списки со списками или кортежи с кортежами — результат будет содержать элементы последовательностей-"слагаемых", причем обратите внимание, что порядок элементов<br />
всегда строго сохраняется:<br />
<source lang="python"><br />
>>> b = [3,4,5]<br />
>>> c = [1,2]<br />
>>> d = b + c + [9,8,7]<br />
>>> print d<br />
[3, 4, 5, 1, 2, 9, 8, 7]<br />
>>> d = [9,8,7] + c + b<br />
>>> print d<br />
[9, 8, 7, 1, 2, 3, 4, 5]<br />
>>> (1,2) + (3,4)<br />
(1, 2, 3, 4)<br />
</source><br />
Теперь самое время познакомиться с циклом for. Он позволяет<br />
проходить по каждому элементу последовательности, выполняя те<br />
или иные действия:<br />
<source lang="python"><br />
>>> a = [1,2,3,4,5]<br />
>>> for i in a:<br />
... print i * 2,<br />
...<br />
2 4 6 8 10<br />
</source><br />
Про отступы, думаю, вы помните. Запятая после операнда в операторе print отменяет перевод строки, благодаря чему выводимые<br />
значения располагаются на одной строке. Для организации привычного многим цикла «от X до Y» используется функция range(X, Y),<br />
генерирующая нужную последовательность:<br />
<source lang="python"><br />
>>> for i in range(3, 8):<br />
... print i,<br />
...<br />
3 4 5 6 7<br />
</source><br />
Как видите, последний индекс диапазона в результирующую последовательность, как и в случае со срезами, не включается.<br />
Постарайтесь не забывать об этой особенности, и ошибок в ваших<br />
программах будет немного меньше.<br />
<br />
Еще один тип последовательности — строка. При некотором допущении она может рассматриваться как кортеж символов (в том плане,<br />
что не позволяет выполнять изменение отдельных элементов «на<br />
месте»). Строка допускает операции среза, ее можно использовать в<br />
цикле for для прохода по каждой букве, и так далее.<br />
<br />
Помимо скалярных типов данных и последовательностей, Python<br />
поддерживает так называемые словари. Словарь — это набор пар<br />
«ключ — значение» (в Perl это называется хэшем, можно встретить и<br />
термин «ассоциативный массив»). Ключ должен быть уникален в<br />
пределах словаря (именно по нему выполняется поиск нужного элемента), и в отличие от рассмотренных выше последовательностей,<br />
порядок элементов в словаре не определен. Синтаксис и основные<br />
операции, которые вы можете выполнять над словарями, продемонстрированы в примере:<br />
<source lang="python"><br />
>>> dict = {<br />
... 'ru': 'Russia',<br />
... 'uk': 'United Kingdom',<br />
... }<br />
>>> print dict<br />
{'ru': 'Russia', 'uk': 'United Kingdom'}<br />
>>> dict.pop('uk')<br />
'United Kingdom'<br />
>>> print dict<br />
{'ru': 'Russia'}<br />
>>> dict['us'] = 'USA'<br />
>>> print dict<br />
{'ru': 'Russia', 'us': 'USA'}<br />
>>> print dict['ru']<br />
Russia<br />
>>> dict.keys()<br />
['ru', 'us']<br />
>>> dict.values()<br />
['Russia', 'USA']<br />
>>> dict.items()<br />
[('ru', 'Russia'), ('us', 'USA')]<br />
</source><br />
Запись присвоения переменной dict выполнена на нескольких<br />
строках для удобства представления (внутри фигурных скобок вы<br />
можете переносить строки и устанавливать любые отступы; аналогично можно поступать и со списками и кортежами). Но вы вполне<br />
можете записывать все в одной строке. Обращение к элементу словаря по ключу выполняется так же, как вы выбор элемента списка по<br />
индексу (с той разницей, что ключ не обязан быть целым числом).<br />
Если присвоить значение несуществующему элементу, то он добавится в словарь. Последние три метода, показанные в примере, позволяют получить соответствующие списки (ключей, значений и кортежей<br />
«ключ-значение»), которые могут быть использованы, например, для<br />
обработки словаря в цикле:<br />
<source lang="python"><br />
>>> arkeys = dict.keys()<br />
>>> arkeys.sort()<br />
>>> for domain in arkeys:<br />
... print "%s = %s" % (domain, dict[domain])<br />
...<br />
ru = Russia<br />
us = USA<br />
</source><br />
Кстати, переменные, значением которых заполняются знакоместа<br />
%s при выводе текста, если таковых две и больше, должны передаваться как кортеж, то есть в круглых скобках. Может использоваться<br />
и особый «словарный» синтаксис, использование которого будет<br />
продемонстрировано в одном из дальнейших примеров.<br />
<br />
== Функции и модули ==<br />
Чтобы завершить разговор о типах данных, нужно несколько слов<br />
сказать о функциях и модулях. Функция позволяет использовать<br />
один и тот же фрагмент кода в разных частях программы. Различают<br />
встроенные функции (которые «зашиты» в интерпретатор) и пользовательские. О вторых речь пойдет в следующем уроке, а сейчас<br />
коротко остановимся на встроенных.<br />
<br />
В первой статье цикла мы уже встречались с функцией float(),<br />
которая преобразует целое число или строку, переданные ей в качестве аргумента, в число с плавающей запятой. Как вы видели, вызов<br />
функции происходит по имени, а в скобках передаются аргументы,<br />
над которыми функция выполняет действия. Функция может не иметь<br />
аргументов, однако указывать скобки после ее имени необходимо.<br />
Результат своей работы функция возвращает основной программе<br />
(причем вызов функции трактуется в выражениях именно как это возвращаемое значение; например, в выражении sum = z + float(b) к<br />
переменной z добавится результат, возвращенный функцией, а не<br />
сама функция). Функция может и не возвращать значения явно — в<br />
этом случае возвращается результат специального типа None.<br />
<br />
Вернемся к типам данных. Полный список поддерживаемых<br />
типов можно получить с помощью следующего кода (не пугайтесь,<br />
ниже я все объясню):<br />
<source lang="python"><br />
>>> import types<br />
>>> for t in [t for t in dir(types) if t[0:2] != '__']:<br />
... print t<br />
</source><br />
Первой строкой мы подключаем один из системных модулей -<br />
types. Модуль — это программа на Python, содержащая функции,<br />
переменные, классы и т. д., которые вы можете в дальнейшем<br />
использовать в своих сценариях. Подробнее о них разговор у нас<br />
пойдет в следующий раз. Пока достаточно знать, что здесь мы подгружаем модуль types и получаем доступ к его функциям, служащим<br />
для преобразования типов. Их полный список выводит функция dir(),<br />
ну а про списковые включения вы уже знаете. Поясню только фрагмент if — с его помощью мы исключаем из вывода специальные функции и переменные, которые начинаются двумя символами подчеркивания (здесь мы применяем операцию среза к строке t).<br />
<br />
В результате выполнения этого кода вы получите список из 35<br />
функций преобразования, соответствующих типам Python. Можно<br />
увидеть, что и функции, и классы являются допустимыми типами<br />
данных, что позволяет присваивать их переменным: например, вы<br />
можете записать mydirfunc = dir, и в дальнейшем mydirfunc можно<br />
будет использовать точно так же, как и функцию dir: print<br />
mydirfunc(types).<br />
<br />
Типов данных существует достаточно много, но для начала работы с Python достаточно тех, что были описаны выше.<br />
<br />
Подведем итог. Сегодня мы не написали ничего полезного, но<br />
заложили фундамент для дальнейшей работы.</div>Zeggelhttp://wiki.linuxformat.ru/wiki/LXF76:PythonLXF76:Python2010-09-11T09:45:54Z<p>Zeggel: /* Подробнее о типах данных */</p>
<hr />
<div>{{цикл/Python}}<br />
''Часть 2. Возможность выводить строку на экран и делить целые числа — огромный шаг вперед по сравнению с началом прошлого века. Но в наши дни от языка программирования требуется несколько большее, так что сегодня мы продолжаем осваивать Python вместе с '''Сергеем Супруновым'''.''<br />
<br />
== Подробнее о типах данных ==<br />
Как мы увидели на прошлом уроке, Python различает строки, целые числа и числа с плавающей запятой. Естественно, на этом его возможности не заканчиваются. Сегодня мы подробнее остановимся на оставшихся типах данных,<br />
чтобы в дальнейшем знать, с чем мы имеем дело. Начнем с последовательностей — списков, кортежей и строк.<br />
<br />
Список — это набор переменных различных типов, упорядоченный<br />
по мере добавления новых элементов. Доступ к элементу осуществляется по его порядковому номеру в последовательности (индексу). Если<br />
проводить аналогию с другими языками программирования, то этот<br />
тип данных наиболее близок к массивам.<br />
<br />
Задается список с помощью квадратных скобок, в которых элементы перечислены через запятую: [0, 1, 'два', 3.0, «четыре»]. Причем в<br />
отличие, скажем, от языка Pascal, вы вполне можете смешивать в<br />
одном списке данные разных типов. Индекс элемента, который вы<br />
хотите получить, задается также в квадратных скобках:<br />
<source lang="python"><br />
>>> a = [0, 1, 'two', 3.0]<br />
>>> print a[1]<br />
1<br />
</source><br />
Как видите, первому элементу списка соответствует индекс 0.<br />
Специального синтаксиса для аналога многомерных массивов не предусмотрено, но вы вполне можете «конструировать» их с помощью<br />
вложенных списков, когда элементом списка является другой список:<br />
<source lang="python"><br />
>>> a = [[1,2,3],[4,5,6]]<br />
>>> a[0]<br />
[1, 2, 3]<br />
>>> a[0][0]<br />
1<br />
>>> a[0][0] = 1234<br />
>>> a<br />
[[1234, 2, 3], [4, 5, 6]]<br />
</source><br />
Для изменения списка существует ряд методов (почти все элементы в Python являются объектами классов, о чем мы поговорим в<br />
одном из следующих уроков; к терминологии же начнем привыкать<br />
уже сейчас). Например, append() позволяет добавлять новые элементы в конец списка:<br />
<source lang="python"><br />
>>> a = []<br />
>>> a.append('q')<br />
>>> a.append(123)<br />
>>> a.append(a)<br />
>>> print a<br />
['q', 123, [...]]<br />
>>> print a[2]<br />
['q', 123, [...]]<br />
>>> print a[2][2][2][2][0]<br />
q<br />
</source><br />
Интересно, не правда ли? Тут мы столкнулись со специальным<br />
типом данных — Ellipsis (отображается как троеточие). Он «зацикливает» последовательность саму на себя (обратите внимание, оператор print a[2] дал точно такой же результат, как и print a), в итоге<br />
получается своего рода бесконечная последовательность. Обычно<br />
используется при обработке многомерных матриц.<br />
<br />
Рассмотрим еще несколько часто используемых методов:<br />
<source lang="python"><br />
>>> a = [1,2]<br />
>>> a.insert(0,5)<br />
>>> a<br />
[5, 1, 2]<br />
>>> a.remove(1)<br />
>>> a<br />
[5, 2]<br />
>>> a.extend(a)<br />
>>> a<br />
[5, 2, 5, 2]<br />
>>> a.pop()<br />
2<br />
>>> a<br />
[5, 2, 5]<br />
</source><br />
Разберемся, что делает этот код. Метод insert() вставляет элемент, значение которого задано во втором аргументе, начиная с<br />
позиции, заданной первым (в примере вставляем число 5 в начало<br />
списка). С помощью remove() вы можете удалить элемент по значению (если в списке несколько элементов с одним значением, удаляется первый из них). Метод extend() расширяет список заданной<br />
последовательностью (заметьте, как это отличается от append()), ну<br />
и pop() «выталкивает» из списка последний элемент. Удалить элемент по индексу можно оператором del, который справляется с<br />
любыми переменными: del a[1].<br />
<br />
Помимо этого, вы можете использовать методы sort() и<br />
reverse(). Оставим их вам для самостоятельного изучения.<br />
<br />
Для работы со списками в Python существует непревзойденный<br />
по гибкости механизм — так называемые срезы. Например, операция<br />
ar[2:5] возвратит список, содержащий элементы списка ar начиная с<br />
третьего (нумерация — с нуля!) и до шестого (исключительно).<br />
Пропуск того или иного индекса означает «с начала» или «до конца»,<br />
отрицательный индекс — «с конца списка». А с помощью ar[1:8:2]<br />
будут выбраны только четные элементы (каждый второй) из диапазона 1-7. Внимательно рассмотрите приведенные ниже примеры, поэкспериментируйте сами, и вам все станет понятно:<br />
<source lang="python"><br />
>>> a = [0,1,2,3,4,5,6,7,8,9]<br />
>>> a[3:5]<br />
[3, 4]<br />
>>> a[4:], a[:2]<br />
([4, 5, 6, 7, 8, 9], [0, 1])<br />
>>> a[-2:]<br />
[8, 9]<br />
>>> a[:]<br />
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]<br />
>>> a[1:9:3]<br />
[1, 4, 7]<br />
>>> a[::2]<br />
[0, 2, 4, 6, 8]<br />
</source><br />
Следует также сказать про так называемые списковые включения — специальные синтаксические конструкции, позволяющие генерировать список на базе другого:<br />
<source lang="python"><br />
>>> a = [b**2 for b in [1,2,3,4,5] if b > 2]<br />
>>> print a<br />
[9, 16, 25]<br />
</source><br />
Оператор «**» — это возведение в степень. Секция if спискового<br />
включения может быть опущена (в ней задается фильтрующее условие). Вместо явного указания списка (после in) вы, естественно,<br />
можете использовать и переменную, содержащую последовательность. Поэкспериментируйте со списковыми включениями — с их<br />
помощью можно достигать удивительных результатов.<br />
<br />
Кортеж — это неизменяемый список. Элементы в нем упорядочены по индексам, обращаться вы можете к ним так же, как и в списке,<br />
но методы, изменяющие кортеж, отсутствуют. Содержимое кортежа<br />
записывается в круглых скобках — tuple = (1, 2, «three»). Если<br />
вам нужно задать кортеж из одного элемента, поставьте после него<br />
запятую — ('5',).<br />
<br />
Замечу, что операции среза применимы и к кортежам (поскольку<br />
сам кортеж при этом не изменяется, а просто создается новая переменная, тоже кортеж, на его основе).<br />
<br />
Кортежи работают быстрее списков, поэтому, если вы не планируете изменять последовательность, то лучше использовать именно их.<br />
<br />
Вы можете складывать списки со списками или кортежи с кортежами — результат будет содержать элементы последовательностей-"слагаемых", причем обратите внимание, что порядок элементов<br />
всегда строго сохраняется:<br />
<source lang="python"><br />
>>> b = [3,4,5]<br />
>>> c = [1,2]<br />
>>> d = b + c + [9,8,7]<br />
>>> print d<br />
[3, 4, 5, 1, 2, 9, 8, 7]<br />
>>> d = [9,8,7] + c + b<br />
>>> print d<br />
[9, 8, 7, 1, 2, 3, 4, 5]<br />
>>> (1,2) + (3,4)<br />
(1, 2, 3, 4)<br />
</source><br />
Теперь самое время познакомиться с циклом for. Он позволяет<br />
проходить по каждому элементу последовательности, выполняя те<br />
или иные действия:<br />
<source lang="python"><br />
>>> a = [1,2,3,4,5]<br />
>>> for i in a:<br />
... print i * 2,<br />
...<br />
2 4 6 8 10<br />
</source><br />
Про отступы, думаю, вы помните. Запятая после операнда в операторе print отменяет перевод строки, благодаря чему выводимые<br />
значения располагаются на одной строке. Для организации привычного многим цикла «от X до Y» используется функция range(X, Y),<br />
генерирующая нужную последовательность:<br />
<source lang="python"><br />
>>> for i in range(3, 8):<br />
... print i,<br />
...<br />
3 4 5 6 7<br />
</source><br />
Как видите, последний индекс диапазона в результирующую последовательность, как и в случае со срезами, не включается.<br />
Постарайтесь не забывать об этой особенности, и ошибок в ваших<br />
программах будет немного меньше.<br />
<br />
Еще один тип последовательности — строка. При некотором допущении она может рассматриваться как кортеж символов (в том плане,<br />
что не позволяет выполнять изменение отдельных элементов «на<br />
месте»). Строка допускает операции среза, ее можно использовать в<br />
цикле for для прохода по каждой букве, и так далее.<br />
<br />
Помимо скалярных типов данных и последовательностей, Python<br />
поддерживает так называемые словари. Словарь — это набор пар<br />
«ключ — значение» (в Perl это называется хэшем, можно встретить и<br />
термин «ассоциативный массив»). Ключ должен быть уникален в<br />
пределах словаря (именно по нему выполняется поиск нужного элемента), и в отличие от рассмотренных выше последовательностей,<br />
порядок элементов в словаре не определен. Синтаксис и основные<br />
операции, которые вы можете выполнять над словарями, продемонстрированы в примере:<br />
<source lang="python"><br />
>>> dict = {<br />
... 'ru': 'Russia',<br />
... 'uk': 'United Kingdom',<br />
... }<br />
>>> print dict<br />
{'ru': 'Russia', 'uk': 'United Kingdom'}<br />
>>> dict.pop('uk')<br />
'United Kingdom'<br />
>>> print dict<br />
{'ru': 'Russia'}<br />
>>> dict['us'] = 'USA'<br />
>>> print dict<br />
{'ru': 'Russia', 'us': 'USA'}<br />
>>> print dict['ru']<br />
Russia<br />
>>> dict.keys()<br />
['ru', 'us']<br />
>>> dict.values()<br />
['Russia', 'USA']<br />
>>> dict.items()<br />
[('ru', 'Russia'), ('us', 'USA')]<br />
</source><br />
Запись присвоения переменной dict выполнена на нескольких<br />
строках для удобства представления (внутри фигурных скобок вы<br />
можете переносить строки и устанавливать любые отступы; аналогично можно поступать и со списками и кортежами). Но вы вполне<br />
можете записывать все в одной строке. Обращение к элементу словаря по ключу выполняется так же, как вы выбор элемента списка по<br />
индексу (с той разницей, что ключ не обязан быть целым числом).<br />
Если присвоить значение несуществующему элементу, то он добавится в словарь. Последние три метода, показанные в примере, позволяют получить соответствующие списки (ключей, значений и кортежей<br />
«ключ-значение»), которые могут быть использованы, например, для<br />
обработки словаря в цикле:<br />
<source lang="python"><br />
>>> arkeys = dict.keys()<br />
>>> arkeys.sort()<br />
>>> for domain in arkeys:<br />
... print "%s = %s" % (domain, dict[domain])<br />
...<br />
ru = Russia<br />
us = USA<br />
</source><br />
Кстати, переменные, значением которых заполняются знакоместа<br />
%s при выводе текста, если таковых две и больше, должны передаваться как кортеж, то есть в круглых скобках. Может использоваться<br />
и особый «словарный» синтаксис, использование которого будет<br />
продемонстрировано в одном из дальнейших примеров.<br />
<br />
== Функции и модули ==<br />
Чтобы завершить разговор о типах данных, нужно несколько слов<br />
сказать о функциях и модулях. Функция позволяет использовать<br />
один и тот же фрагмент кода в разных частях программы. Различают<br />
встроенные функции (которые «зашиты» в интерпретатор) и пользовательские. О вторых речь пойдет в следующем уроке, а сейчас<br />
коротко остановимся на встроенных.<br />
<br />
В первой статье цикла мы уже встречались с функцией float(),<br />
которая преобразует целое число или строку, переданные ей в качестве аргумента, в число с плавающей запятой. Как вы видели, вызов<br />
функции происходит по имени, а в скобках передаются аргументы,<br />
над которыми функция выполняет действия. Функция может не иметь<br />
аргументов, однако указывать скобки после ее имени необходимо.<br />
Результат своей работы функция возвращает основной программе<br />
(причем вызов функции трактуется в выражениях именно как это возвращаемое значение; например, в выражении sum = z + float(b) к<br />
переменной z добавится результат, возвращенный функцией, а не<br />
сама функция). Функция может и не возвращать значения явно — в<br />
этом случае возвращается результат специального типа None.<br />
<br />
Вернемся к типам данных. Полный список поддерживаемых<br />
типов можно получить с помощью следующего кода (не пугайтесь,<br />
ниже я все объясню):<br />
<source lang="python"><br />
>>> import types<br />
>>> for t in [t for t in dir(types) if t[0:2] != '__']:<br />
... print t<br />
</source><br />
Первой строкой мы подключаем один из системных модулей -<br />
types. Модуль — это программа на Python, содержащая функции,<br />
переменные, классы и т. д., которые вы можете в дальнейшем<br />
использовать в своих сценариях. Подробнее о них разговор у нас<br />
пойдет в следующий раз. Пока достаточно знать, что здесь мы подгружаем модуль types и получаем доступ к его функциям, служащим<br />
для преобразования типов. Их полный список выводит функция dir(),<br />
ну а про списковые включения вы уже знаете. Поясню только фрагмент if — с его помощью мы исключаем из вывода специальные функции и переменные, которые начинаются двумя символами подчеркивания (здесь мы применяем операцию среза к строке t).<br />
<br />
В результате выполнения этого кода вы получите список из 35<br />
функций преобразования, соответствующих типам Python. Можно<br />
увидеть, что и функции, и классы являются допустимыми типами<br />
данных, что позволяет присваивать их переменным: например, вы<br />
можете записать mydirfunc = dir, и в дальнейшем mydirfunc можно<br />
будет использовать точно так же, как и функцию dir: print<br />
mydirfunc(types).<br />
<br />
Типов данных существует достаточно много, но для начала работы с Python достаточно тех, что были описаны выше.<br />
<br />
Подведем итог. Сегодня мы не написали ничего полезного, но<br />
заложили фундамент для дальнейшей работы.</div>Zeggelhttp://wiki.linuxformat.ru/wiki/LXF74-75:PythonLXF74-75:Python2010-09-11T09:19:59Z<p>Zeggel: /* Первая программа */</p>
<hr />
<div>{{цикл/Python}}<br />
''ЧАСТЬ 1 Язык программирования Python становится достаточно популярным и уже практически на равных может бороться за благосклонность пользователей с таким бывалым соперником, как Perl. Поэтому с ним стоит познакомиться, считает '''Сергей Супрунов'''.''<br />
<br />
== Немного истории ==<br />
Началось все в далеком 1990 году, когда Гвидо ван Россум<br />
(Guido van Rossum) разработал первую версию языка Python,<br />
который появился в свободном доступе в 1991 году. Первоначально созданный как язык сценариев для разрабатываемой Россумом системы<br />
Amoeba, он оказался настолько хорош и переносим, что достаточно быстро получил распространение на самых различных операционных системах.<br />
<br />
Сейчас этот язык входит в поставку практически всех популярных<br />
дистрибутивов Linux; его, наряду с Perl, поддерживают Apache<br />
(модуль mod_python), PostgreSQL (процедурный язык PL/Python) и<br />
многие другие программы.<br />
<br />
== Отличительные особенности ==<br />
Почему же Python столь стремительно завоевывает популярность?<br />
<br />
Прежде всего, будучи интерпретируемым языком, Python не требует компиляции, компоновки и прочих «премудростей» — сценарий на<br />
Python может быть запущен практически сразу же после редактирования. Это существенно снижает время разработки и делает Python весьма удобным для таких задач как создание прототипов программ, проверка работоспособности того или иного алгоритма, а также для администрирования, где время исполнения — гораздо менее важный фактор,<br />
чем удобство модификации сценария.<br />
<br />
Вторым большим плюсом этого языка является уже упоминавшаяся<br />
переносимость между различными системами. Если вы не используете<br />
специфические особенности платформы (например, команду fork для<br />
ветвления процессов), то с большой долей вероятности ваш код, разработанный в Linux, сможет работать и во FreeBSD, и даже в Windows.<br />
<br />
Далее, поскольку Python — язык высокого уровня, он позволяет<br />
вам сосредоточиться на алгоритме, на логике программы, не отвлекаясь на описание переменных, выделение памяти и т. п.<br />
<br />
Ну и самое главное — Python разрабатывается как проект opensource,<br />
то есть вы можете не только использовать его в своей работе<br />
без каких-либо ограничений, но и активно участвовать в его развитии.<br />
<br />
Все это делает Python хорошим выбором для самого широкого<br />
спектра задач — от автоматизации рутинных операций по администрированию и разработки графических «оберток» для консольных утилит<br />
до web-программирования и разработки прототипов в крупных<br />
проектах.<br />
<br />
== Где его взять? ==<br />
Большинству пользователей Linux об этом беспокоиться не нужно -<br />
Python входит почти во все популярные дистрибутивы. Откройте окно<br />
терминала, наберите там команду python, и если в ответ увидите сообщение о версии интерпретатора и приглашение «>>>», значит, он у вас<br />
уже есть. Если же вам не повезло и вы увидели сообщение «Command<br />
not found», то придется озаботиться его установкой.<br />
<br />
Свежую версию Python (архив с исходными кодами) всегда можно<br />
найти на официальной странице: http://www.python.org/download/ .<br />
Кроме того, вы наверняка сможете найти пакет, подготовленный для<br />
вашей операционной системы.<br />
<br />
== Знакомство с интерактивной оболочкой и основы синтаксиса ==<br />
Для первоначального изучения очень удобен интерактивный<br />
режим — вы сразу же получаете результат выполнения введенной<br />
команды, и в случае ошибки можете проанализировать причины ее<br />
возникновения и исправиться.<br />
<br />
Так что вводите команду python в окне терминала, и — вперед! Для<br />
начала потренируемся с математикой (после ввода команды в строке<br />
приглашения, которая отмечается символами «>>>» следует нажимать<br />
[Enter], чтобы увидеть результат):<br />
<source lang="python"><br />
>>> 1+3<br />
4<br />
>>> a=5<br />
>>> 3 + a<br />
8<br />
>>> a / 3<br />
1<br />
</source><br />
Ага, вот и первый сюрприз. Как и в языке C, при делении целого<br />
числа на целое результат — тоже целое число, дробная часть отбрасывается. Чтобы обойти эту особенность, один из операндов нужно сделать числом с плавающей запятой:<br />
<source lang="python"><br />
>>> a / 3.0<br />
1.6666666666666667<br />
>>> (a * 1.0) / 3<br />
1.6666666666666667<br />
</source><br />
Этот пример показывает, что в Python существует понятие «тип<br />
переменной», и если преобразование между типами не лишено смысла, то оно выполняется прозрачно для программиста. Впрочем, можно<br />
использовать и явное преобразование:<br />
<source lang="python"><br />
>>> float(a) / 3<br />
1.6666666666666667<br />
</source><br />
В текущей версии языка для целочисленного деления существует<br />
отдельный оператор — «//». Сейчас выражения 3/2 и 3//2 вернут один<br />
и тот же результат, но в будущих версиях поведение «традиционного»<br />
оператор деления («/») может быть приведено к привычному для человека, когда 3/2 = 1.5.<br />
<br />
Операция сложения допустима и для строк (которые могут быть<br />
заключены как в апострофы, так и в кавычки):<br />
<source lang="python"><br />
>>> 'Hello, ' + "world!"<br />
'Hello, world!'<br />
>>> "127" + 5<br />
Traceback (most recent call last):<br />
File "<stdin>", line 1, in ?<br />
TypeError: cannot concatenate 'str' and 'int' objects<br />
</source><br />
А вот смешивать символьные типы с числовыми нельзя — это вам<br />
не Perl! Еще одна интересная операция для строк — повторение:<br />
<source lang="python"><br />
>>> '=' * 25<br />
'========================='<br />
</source><br />
При выводе динамически формируемых текстовых строк важное<br />
значение имеют символы подстановки:<br />
<source lang="python"><br />
>>> language = 'Python'<br />
>>> print "I like %s" % language<br />
I like Python<br />
</source><br />
Здесь мы в выводимом тексте создаем так называемое «знакоместо» %s, которое затем заполняется значением переменной, стоящей<br />
после оператора %. В последующих статьях цикла мы познакомимся с<br />
ними более подробно. Ну а оператор print, думаю, пояснять не нужно -<br />
он просто выводит строку на экран (обратите внимание на отсутствие<br />
апострофов в выводе команды).<br />
<br />
Чтобы выйти из командной оболочки, нажмите [Ctrl]+[D].<br />
<br />
== Первая программа ==<br />
Настало время написать первую настоящую программу. Откройте ваш<br />
любимый текстовый редактор. Я предпочитаю работать в vi, но вы<br />
вполне можете выбрать и более привычный инструмент; кроме того,<br />
существует немало редакторов, обладающих рядом сервисных функций, таких как подсветка синтаксиса, автоотступ и т. д. Один из них, Eric,<br />
рассматривается в разделе HotPicks. Вы также можете обратить внимание на KDevelop и IDLE, редактор, поставляемый вместе с Python.<br />
Наберите приведенный ниже код. Немного нарушив традицию, мы сразу приступим к сравнительно сложному примеру, который позволит<br />
познакомиться с большинством синтаксических особенностей языка.<br />
Да и «Hello, World!» мы фактически уже написали, когда были в интерактивной оболочке. Еще одна просьба — когда будете вводить код, не<br />
спешите читать его описание далее в этой статье. Постарайтесь догадаться сами, что делает этот сценарий — это совсем не сложно. Итак,<br />
код (сохраните его в файле test1.py):<br />
<source lang="python"><br />
#!/usr/bin/python<br />
prompt = '> '<br />
cmd = 'nocmd'<br />
while cmd != 'exit':<br />
cmd = raw_input(prompt)<br />
if cmd == 'about':<br />
print 'It is my first python script'<br />
elif cmd == 'help':<br />
print '''Commands:<br />
about – about this program<br />
help – this information<br />
exit – quit the program'''<br />
elif cmd =='exit':<br />
pass # пустая команда – не делает ничего<br />
else:<br />
print 'Command not found. Type "help"'<br />
print 'Bye.'<br />
</source><br />
Для удобства чтения строковые константы выделены в тексте курсивом. Надеюсь, вы уже поняли, что приведенный скрипт должен<br />
будет имитировать работу простейшей командной оболочки, запрашивая у пользователя команды и выводя результат их исполнения. Таких<br />
команд три:<br />
* about: вывести информацию о программе;<br />
* help: напечатать краткую справку по работе с программой;<br />
* exit: команда выхода из программы.<br />
<br />
В этом фрагменте мы встречаемся с одним из циклов (while, другой популярный цикл — for — рассмотрим в следующей статье) и оператором ветвления if-elif-else. Если вы знакомы с каким-нибудь языком программирования, то все вам будет понятно. Но обратите внимание на синтаксис: в Python неотъемлемой частью программы являются<br />
отступы. Именно они показывают интерпретатору, где заканчивается<br />
тот или иной блок кода. В приведенном выше примере последняя строка будет выполнена при выходе из цикла, поскольку она не имеет<br />
отступа и потому телу цикла while не принадлежит.<br />
<br />
Особо следует пояснить отсутствие отступа в строках, заключенных<br />
в тройные апострофы (фрагмент elif, отвечающий за выполнение<br />
команды «help»). Такие строки могут содержать в себе и символы<br />
перевода строки, и табуляцию. Интерпретатор воспринимает все это<br />
как одну строковую константу — на экран все будет выведено именно<br />
так, как набрано в коде сценария. (Чтобы было проще понять программу, замените на первых порах эту строку обычной, — тогда она не будет<br />
сбивать вас с толку и лучше будет видно структуру сценария).<br />
<br />
На Unix-подобных системах очень важную роль играет самая первая строка сценария — в ней следует указать путь к интерпретатору<br />
python (обычно это /usr/bin/python или /usr/local/bin/python). В<br />
остальных строках символ «#» означает начало комментария — все,<br />
что за ним следует, интерпретатором игнорируется.<br />
<br />
Осталось сделать наш файл исполняемым (chmod +x test1.py)<br />
и убедиться, что все работает правильно:<br />
<source lang="text"><br />
serg$ ./test1.py<br />
> hello<br />
Command not found. Type "help"<br />
> help<br />
Commands:<br />
about – about this program<br />
help – this information<br />
exit – quit the program<br />
> about<br />
It is my first python script<br />
> exit<br />
Bye.<br />
</source><br />
В случае ошибок проверяйте синтаксис, особенно отступы. И не<br />
забудьте убедиться, что вы используете именно тот путь к интерпретатору, который принят в вашем дистрибутиве.<br />
<br />
Ну что ж. Для первого урока, думаю, достаточно. В следующий раз<br />
мы рассмотрим так называемые последовательности (списки, кортежи<br />
и словари) — очень важные типы данных, делающие Python столь мощным языком программирования, а также затронем основы работы<br />
с функциями и модулями.</div>Zeggel