Журнал LinuxFormat - перейти на главную

LXF77:Python

Материал из Linuxformat
Перейти к: навигация, поиск

Часть 3. Итак, познакомившись с типами данных, доступных в языке Python, мы, под чутким руководством Сергея Супрунова морально готовы приступить к более серьёзным вещам. На сегодня программа-минимум – разобраться с модулями и научиться писать свои функции.

Содержание

Модули

Начнем со стандартных модулей. Стандартными их называют потому, что они, как правило, уже включены в вашу поставку Python (будь то Linux, FreeBSD или даже Windows) и не требуют дополнительной инсталляции. Как вы видели в конце прошлого урока, модуль подключается оператором import. В качестве параметров вы можете указать любое количество модулей. Также допускается любое число операторов import в любой точке вашей программы.

Для чего же нужны модули? Чуть позже, когда мы напишем свою функцию, вы увидите, что с помощью модуля очень легко реализуется концепция повторного использования кода. Пока же модули интересны нам как способ расширения возможностей вашей программы. С их помощью вы подключаете уже написанные кем-то наборы функций и методов, которые сможете использовать почти так же, как если бы они были встроенными (такими, как рассмотренная нами ранее float()).

Начнем с модуля sys. В нем определен ряд переменных, содержащих информацию об операционной системе, дескрипторы стандартных потоков ввода, вывода и ошибок (stdin, stdout и stderr соответственно), и так далее. рассмотрим небольшой пример:

>>> import sys
>>> print sys.arch, sys.platform
 i386 linux2
>>> print sys.version
 2.4.1 (#1, Sep 13 2005, 00:39:20)
 [GCC 4.0.2 20050901 (prerelease) (SUSE Linux)]
>>> print sys.maxint
 2147483647

Как видите, чтобы получить доступ к определённым в модуле переменным (впрочем, это относится и к остальным объектам), перед их именем следует указать имя модуля. Это оберегает от конфликта имён, когда объявленная вами переменная или функция имеет такое же имя, как и определенная в модуле. то есть каждый модуль имеет свое пространство имен, доступ к которому осуществляется по имени модуля. Если имя модуля слишком неудобно для работы, вы можете указать для него псевдоним после ключевого слова as (например, import SimpleXMLRPCServer as rpc), и в дальнейшем использовать это упрощённое имя. Впрочем, иногда удобнее (а порой и необходимо), что-бы имена, определенные в модуле, были импортированы непосредственно в пространство имён основной программы. Для этого предусмотрена несколько иная конструкция:

>>> from sys import *
>>> print platform
 linux2

Теперь можно обращаться к объектам модуля непосредственно, но будьте осторожны – вы потеряете все определённые вами переменные и функции, имена которых совпадут с именами определенных в модуле.


Символ «звездочка» в операторе from - import означает, что должно быть импортировано всё, что определено в модуле. Вы также можете перечислить только то, что желаете сделать доступным в вашей про грамме (например, from sys import version).

Ещё одна важнейшая переменная модуля sys – список sys.argv, в который в момент запуска Python-программы помещаются аргументы, переданные в командной строке. Пример использования этого списка вы увидите далее в данной статье.

Модуль os

Пожалуй, самый популярный модуль Python – это os. Он предоставляет вам ряд функций, позволяющих взаимодействовать с операционной системой: chroot(), mkdir(), setuid() и так далее. Названия, думаю, говорят сами за себя. а как посмотреть полный список функций, доступных в модуле, я надеюсь, вы ещё помните с прошлого урока: dir(os).

Для работы с файловой системой практически незаменим подмодуль этого модуля – os.path. С его помощью вы можете определять типы файлов, установленные для них права доступа, и тому подобное. Нам ещё доведётся поработать с ним на практике.

Прочие модули

Вообще, в стандартную поставку Python входит несколько десятков наиболее полезных модулей. Найти их можно в каталоге /usr/lib/python (на некоторых системах путь может быть иным, например, /usr/local/lib/python). Если быть точнее, то Python ищет свои модули в каталогах, список которых возвращает переменная sys.path.

Обращайте внимание на файлы с расширением py (pyc и pyo – это байт-код модулей, который используется для экономии ресурсов, поскольку при обращении к модулю повторная компиляция не требуется). Названия большинства из них говорят сами за себя, к тому же вы можете открыть любой модуль, чтобы ознакомиться с его кодом и, как правило, очень подробными комментариями. С некоторыми из них мы обязательно столкнёмся в дальнейшем.

Функции

Со встроенными функциями вы уже знакомы. Но что делать, если возможностей, заложенных в интерпретатор или стандартные модули, вам недостаточно? Всё просто – напишите собственную функцию!

Пользовательская функция определяется оператором def (от define – определять). В качестве параметра указывается имя функции (оно должно быть уникально в пределах пространства имён основной программы), а в скобках перечисляются её формальные аргументы. Далее ставится двоеточие (как и в случае любых блочных операторов, таких как if или for), и на последующих строках, имеющих отступ, вводится код функции. Впрочем, когда речь идёт о Python, несколько строк кода способны сказать больше, чем пол-страницы текста на естественном языке. Чтобы лучше во всем разобраться, рассмотрим один пример (файл назовем abbr.py):

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
 Программа обслуживает небольшой словарь сокращений, используя anydbm
"""
import sys, anydbm as db
dictfile = 'dict.dbm'
def openDictionary(dbmfile=dictfile):
     """ Открыть словарь """
     global dictionary
     try:
         dictionary = db.open(dbmfile, 'c')
     except:
         raise 'Ошибка открытия файла'
def getMeaning(abbr):
     """ Поиск расшифровки """
     try:
 
        return dictionary[abbr]
     except:
        return '[не определено]'
def addMeaning(abbr, meaning):
     """ Добавить сокращение """
     dictionary[abbr] = meaning
    def delMeaning(abbr):
     """ Удалить сокращение """
     try:
        del dictionary[abbr]
     except:
        pass
if __name__ == "__main__":
     openDictionary()
     try:
        command = sys.argv[1]
        if command == '-a':
            addMeaning(sys.argv[2], sys.argv[3])
        elif command == '-d':
            delMeaning(sys.argv[2])
        else:
            abbr = sys.argv[1]
            print abbr + ' = ' + getMeaning(abbr)
     except:
        print """\
 Неверные аргументы. Допустимый синтаксис:
 abbr.py <ABBR>                  - расшифровать сокращение
 abbr.py -a <ABBR> <MEANING>     - добавить расшифровку
 abbr.py -d <ABBR>                - удалить сокращение
 """
 else:
     openDictionary()

Эта программа реализует простейший консольный словарь сокращений. Только не забудьте сделать файл исполняемым (chmod u+x abbr.py). Поддерживаются три операции (информацию об этом вы получите, если попытаетесь вызвать сценарий с неправильными аргументами):

  1. abbr.py – возвращает из словаря расшифровку сокращения <ABBR>;
  2. abbr.py -a <ABBR> <MEANING> – добавляет в словарь расшифровку сокращения. В силу особенностей словарного типа данных в Python, эта же команда изменяет расшифровку для уже существующей аббревиатуры;
  3. abbr.py -d <ABBR> – удаляет из словаря запись для указанного сокращения.

Обратите внимание на вторую строку – здесь указывается кодировка исходного текста (подробности см. на странице http://www.python.org/peps/pep-0263.html). Если вы используете не UTF-8, то укажите в этой строке свою кодировку (например, koi8-r).

Строки, обрамлённые утроенными кавычками, в данном случае можно рассматривать как многострочные комментарии.

Оператор global в функции openDictionary() делает переменную dictionary доступной за пределами функции. В противном случае её действие распространялось бы только на эту функцию. Ещё один интересный момент – то, как описан формальный аргумент функции. В данном случае мы задаем для переменной значение по умолчанию. Если в дальнейшем при вызове функции вы не передадите в неё аргумент, будет использовано значение переменной dictfile.

Несколько слов нужно сказать о самом модуле anydbm. С его помощью Python выполняет поиск доступного dbm-пакета в текущей системе (вам не нужно об этом беспокоиться). Данные в файле DBM организованы по словарному принципу (ключ – значение), поэтому данный файл может быть естественным образом сопоставлен с переменной типа «словарь». Все дальнейшие операции с данными словаря для программиста выглядят как обычные, а dbm-модуль позаботится о том, чтобы все данные оказались сохранены в файл. Собственно говоря, dbm-файл вы можете рассматривать как словарь, содержимое которого не теряется между запусками программы. также обратите внимание, что при подключении этого модуля мы используем псевдоним.

Итак, в функции openDictionary() мы открываем файл dict.dbm (второй параметр – 'c' – даёт указание создать такой файл, если его ещё нет) и сопоставляем его со словарём dictionary. Конструкция «try – except» служит для обработки ошибок. В блок try мы помещаем потенциально опасные операции (которые могут завершиться с ошибкой), а блок except содержит код, который будет выполнен в случае возникновения ошибки в блоке try. Оператор raise генерирует сообщение об ошибке и прерывает выполнение программы.

Далее описаны три функции, реализующие заявленную выше функциональность. Пожалуй, в пояснении нуждается здесь только оператор pass в функции delMeaning(): это пустой оператор, который ничего не делает – если нужного ключа в словаре нет, то и удалять нечего.

Ну и в конце сценария, в секции оператора if, вы можете увидеть пример обработки аргументов командной строки.

Конечно, этот учебный пример не лишён недостатков: невозможно сделать несколько записей, имеющих одинаковую аббревиатуру, работа чувствительна к регистру символов (введя запись для «UDP», вы не сможете получить значение по ключу «udp»), и т.д. Однако сейчас нам важен не функционал, а собственно языковые конструкции.

Возвращаясь к модулям

Итак, мы написали функцию, которая может оказаться крайне полезной в других программах. Как бы было хорошо, если бы оказалось возможным поместить её в модуль! А ведь нет ничего проще – она уже в модуле. Да-да! Вы можете просто подключить написанную выше программу в качестве модуля (одним из операторов, import или fromimport) и спокойно использовать определённые в ней переменные и функции!

В этом заключается одно из преимуществ Python по сравнению с его «прямым конкурентом» - языком Perl. В Perl вам пришлось бы специально оформлять вашу программу как модуль (как минимум, потребуется оператор package). В Python концепция повторного использования кода заложена в основу синтаксиса и не требует от вас совершенно никаких усилий.

Рассмотрим пример:

#!/usr/bin/python
# -*- coding: utf-8 -*-
 
import abbr
abbr.delMeaning('UDP')
print abbr.getMeaning('IP')

Как видите, вам достаточно импортировать py-программу (расширение не указывается), и вы можете в полной мере воспользоваться всем созданным ранее. Единственное, этот файл должен быть доступен для поиска (самый простой вариант – поместить его в текущий каталог).

Обратите внимание, что в момент импортирования переменная __name__ в подключаемом модуле будет иметь значение, совпадающее с именем модуля. Поэтому в данном случае вместо секции if сценария abbr.py будет выполнена секция else. Подобный оператор if – else присутствует практически в каждой программе на языке Python и позволяет использовать ее и как модуль, и как самостоятельный сценарий (в последнем случае, как нетрудно догадаться, переменная __name__ будет иметь значение "__main__").

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

Персональные инструменты
купить
подписаться
Яндекс.Метрика