Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

[ Россум, Дрейк, Откидач ] Язык программирования Python

.pdf
Скачиваний:
285
Добавлен:
25.04.2014
Размер:
1.5 Mб
Скачать

6.2. Поиск модулей

61

6.2 Поиск модулей

Когда импортируется модуль, например spam, интерпретатор ищет файл с именем ‘spam.py’ в текущем каталоге, затем в каталогах, указанных в переменной окружения PYTHONPATH, затем в зависящих от платформы путях по умолчанию.

Каталоги, в которых осуществляется поиск, хранятся в переменной sys.path. Таким образом, программы на языке Python могут изменять пути поиска модулей во время их выполнения.

6.3“Компилированные” файлы

Для ускорения запуска программ, использующих большое количество модулей, если уже существует файл с именем ‘spam.pyc’ в том же каталоге, где найден ‘spam.py’, считается, что он содержит “байт-компилированный” модуль spam. Если такого файла нет, то он создается, и время последнего изменения ‘spam.py’ записывается в созданном ‘spam.pyc’ (при последующем использовании, ‘.pyc’-файл игнорируется, если исходный ‘.py’-файл был изменен).

Обычно Вам не надо ничего делать для создания ‘spam.pyc’. Как только ‘spam.py’ успешно откомпилирован, интерпретатор пытается записать компилированную версию в ‘spam.pyc’. Если интерпретатору по каким-либо причинам это не удается (например, недостаточно пользовательских полномочий), ошибки не возникает. Если же файл записан не полностью, далее он распознается как неработоспособный и игнорируется. Содержимое байт-компилированных файлов является платформно-независимым (но может быть разным для разных версий интерпретатора), так что каталог с модулями может совместно использоваться машинами с разными архитектурами.

Несколько тонкостей для опытных пользователей:

Если интерпретатор вызывается с опцией -O или переменная окружения PYTHONOPTIMIZE имеет непустое значение, интерпретатор генерирует оптимизированный байт-код и сохраняет его в ‘.pyo’-файлах. В настоящий момент оптимизация дает не слишком много: при этом удаляются инструкции assert, игнорируются инструкции ‘if __debug__: . . . ’, не сохраняется информация о нумерации строк в исходных ‘.py’-файлах. В этом случае оптимизируются все используемые модули, ‘.pyc’-файлы игнорируются.

Опция -OO приводит к тому, что интерпретатор выполняет оптимизацию которая, в некоторых (редких) случаях, может привести к сбоям в работе программ. В настоящий момент, помимо действий, выполняемых с опцией -O, удаляются строки документации, давая более компактные ‘.pyo’-файлы. Так как некоторые программы могут рассчитывать на наличие строк документации, используйте эту опцию с осторожностью.

Для программы, запускаемой из командной строки, байт-код никогда не записывается в ‘.pyc’- или ‘.pyo’-файл. Поэтому, если Вы хотите уменьшить время, требую-

62

Глава 6. Модули

щееся для загрузки, поместите большую часть кода в модуль, оставив в программе лишь загрузочную часть, которая импортирует этот модуль.

Возможно использование модуля (или запуск программы) при наличии ‘.pyc’-файла (или ‘.pyo’-файла, если используется одна из опций -O или -OO), даже если отсутствует ‘.py’-файл. Таким образом, Вы можете распространять библиотеки и программы в виде, из которого относительно сложно извлечь информацию об используемых алгоритмах.

Модуль compileall позволяет создать ‘.pyc’- (или ‘.pyo’-) файлы для всех модулей в каталоге. Это может быть особенно полезно, если вы хотите ограничить доступ к каталогу, в котором находится библиотека. Заметим, что интерпретатор не будет использовать ‘.pyc’-файлы, если он запущен с включенной оптимизацией, и ‘.pyo’-файлы, если оптимизация выключена (если же отсутствует ‘.py’-файл, модуль окажется недоступным).

6.4Стандартные модули

Python распространяется с библиотекой стандартных модулей, которой посвящена третья часть книги. Часть модулей встроена в интерпретатор, обеспечивая доступ к операциям, которые не входят в ядро языка, но, тем не менее, встроены либо из соображений эффективности, либо для обеспечения доступа к примитивам операционной системы. Набор таких модулей зависит от конфигурации, так, например, модуль amoeba присутствует только в системах, которые поддерживают примитивы Amoeba. Один модуль заслуживает особого внимания: sys, который присутствует всегда. Переменные sys.ps1 и sys.ps2 при работе в интерактивном режиме определяют строки, используемые для первичного и вторичного приглашения:

>>>import sys

>>>sys.ps1 ’>>> ’

>>>sys.ps2

’... ’

>>> sys.ps1 = ’C> ’ C> print ’рТЙЧЕФ!’ рТЙЧЕФ!

C>

Переменная sys.path содержит список строк с именами каталогов, в которых происходит поиск модулей. Она инициализируется из значения переменной окружения PYTHONPATH и встроенного значения по умолчанию. Вы можете изменить ее значение, используя стандартные операции со списками:

>>>import sys

>>>sys.path.append(’/ufs/guido/lib/python’)

6.5. Функция dir()

63

6.5 Функция dir()

Для выяснения имен, определенных в модуле, можно использовать встроенную функцию dir(). Она возвращает отсортированный список строк:

>>>import fibo, sys

>>>dir(fibo)

[’__name__’, ’fib’, ’fib2’]

>>> dir(sys)

[’__name__’, ’argv’, ’builtin_module_names’, ’copyright’, ’exit’, ’maxint’, ’modules’, ’path’, ’ps1’, ’ps2’, ’setprofile’, ’settrace’, ’stderr’, ’stdin’, ’stdout’, ’version’]

Без аргументов, dir() возвращает список имен, определенных в текущей области видимости:

>>>a = [1, 2, 3, 4, 5]

>>>import fibo, sys

>>>fib = fibo.fib

>>>dir()

[’__name__’, ’a’, ’fib’, ’fibo’, ’sys’]

Обратите внимание, что перечисляются имена объектов всех типов: переменные, модули, функции и т. д.

Список, возвращаемый функцией dir() не содержит имена встроенных функций

ипеременных — они определены в стандартном модуле __builtin__:

>>>import __builtin__

>>>dir(__builtin__)

[’AccessError’, ’AttributeError’, ’ConflictError’, ’EOFError’, ’IOError’, ’ImportError’, ’IndexError’, ’KeyError’, ’KeyboardInterrupt’, ’MemoryError’, ’NameError’, ’None’, ’OverflowError’, ’RuntimeError’, ’SyntaxError’, ’SystemError’, ’SystemExit’, ’TypeError’, ’ValueError’, ’ZeroDivisionError’, ’__name__’, ’abs’, ’apply’, ’chr’, ’cmp’, ’coerce’,

’compile’, ’dir’, ’divmod’, ’eval’, ’execfile’, ’filter’, ’float’, ’getattr’, ’hasattr’, ’hash’, ’hex’, ’id’, ’input’, ’int’, ’len’, ’long’, ’map’, ’max’, ’min’, ’oct’, ’open’, ’ord’, ’pow’, ’range’, ’raw_input’, ’reduce’, ’reload’, ’repr’, ’round’,

’setattr’, ’str’, ’type’, ’xrange’]

64

Глава 6. Модули

6.6Пакеты

Пакеты — способ структурирования пространств имен модулей, используя “точечную запись”. Например, имя модуля A.B обозначает подмодуль с именем A в пакете B. Так же, как использование модулей делает безопасным использование глобального пространства имен авторами различных модулей, использование точечной записи делает безопасным использование имен модулей авторами многомодульных пакетов.

Предположим, Вы хотите спроектировать совокупность модулей (“пакет”) для единообразной обработки звуковых файлов и данных. Существует множество форматов звуковых файлов (обычно распознаваемых по их расширению, например ‘.wav’, ‘.aiff’, ‘.au’), так что Вам необходимо создавать и поддерживать все возрастающий набор модулей для преобразования между различными форматами файлов. Вы можете захотеть выполнять множество различных операций над звуковыми данными (микширование, добавление эха, частотная обработка, создание искусственного стереоэффекта), то есть, вдобавок, Вы будете писать нескончаемый поток модулей для выполнения этих операций. Вот примерная структура Вашего пакета (выраженная в терминах иерархической файловой системы):

Sound/

чЕТИОЙК ХТПЧЕОШ РБЛЕФБ

__init__.py

йОЙГЙБМЙЪБГЙС РБЛЕФБ

Formats/

тБВПФБ У ЖБКМБНЙ

__init__.py

 

wavread.py

 

wavwrite.py

 

aiffread.py

 

aiffwrite.py

 

auread.py

 

auwrite.py

 

...

 

Effects/

ъЧХЛПЧЩЕ ЬЖЖЕЛФЩ

__init__.py

 

echo.py

 

surround.py

 

reverse.py

 

...

 

Filters/

жЙМШФТЩ

__init__.py

 

equalizer.py

 

vocoder.py

 

karaoke.py

 

...

 

Файл ‘__init__.py’ необходим для того, чтобы Python распознавал каталог, как содержащий пакет — таким образом предотвращается маскировка полноценных модулей, расположенных далее в путях поиска, каталогами с распространенными именами (такими как ‘string’). В простейшем случае, ‘__init__.py’ — пустой файл, но может содер-

6.6. Пакеты

65

жать код инициализации пакета и/или устанавливать переменную __all__, описанную ниже.

Пользователи пакета могут импортировать индивидуальные модули пакета, напри-

мер:

import Sound.Effects.echo

В этом случае загружается модуль Sound.Effects.echo. На него нужно ссылаться по полному имени:

Sound.Effects.echo.echofilter(input, output, delay=0.7, atten=4)

Вы можете использовать альтернативный способ импортирования подмодуля:

from Sound.Effects import echo

В этом случае также загружается модуль Sound.Effects.echo, и делает его доступным для использования без префикса:

echo.echofilter(input, output, delay=0.7, atten=4)

Еще один вариант — импортировать желаемую функцию или переменную непосредственно:

from Sound.Effects.echo import echofilter

И в этом случае загружается модуль Sound.Effects.echo, но на этот раз, функция echofilter() становится доступной для использования непосредственно:

echofilter(input, output, delay=0.7, atten=4)

Заметим, что при использовании ‘from package import item’, item может быть модулем, подпакетом или другим именем, определенном в пакете package, таким как функция, класс или переменная. Инструкция import сначала проверяет, определено ли имя item в пакете, если нет, считает его модулем и пытается загрузить. Если при загрузке возникает ошибка, генерируется исключение ImportError.

И наоборот, при использовании инструкции ‘import item.subitem.subsubitem’, каждая единица, кроме последней, должна быть пакетом. Последняя единица может быть модулем или пакетом, но не может быть классом, функцией или переменной, определенной в предыдущей единице.

66

Глава 6. Модули

6.6.1Импортирование всего содержимого пакета (модуля)

Что же

происходит, когда пользователь использует ‘from Sound.Effects

import

*’? В идеале, интерпретатор должен каким-либо образом обойти файлы, на-

ходящиеся в каталоге пакета, и импортировать их все. К сожалению, такой подход не будет работать достаточно хорошо на таких платформах, как Macintosh и Windows, где файловая система не всегда имеет точную информацию о регистре букв в именах файлов. В этом случае нет надежного пути узнать, с каким именем должен быть импортирован файл с именем ‘ECHO.PY’: echo, Echo или ECHO.

Единственный выход для автора — снабдить пакет явным указателем его содержимого. Инструкция import использует следующее соглашение: если в инициализационном файле ‘__init__.py’ определен список с именем __all__, он используется в качестве списка имен модулей, которые должны импортироваться при использовании ‘from package import *’. Поддержка этого списка в соответствии с текущим составом пакета возлагается на автора. Можно также не определять список __all__, если авторы не считают уместным импортирование *. Например, файл ‘Sounds/Effects/__init__.py’ может содержать следующий код:

__all__ = ["echo", "surround", "reverse"]

Это означает, что from Sound.Effects import * импортирует три указанных модуля из пакета Sound.

Если список __all__ не определен, ‘from Sound.Effects import *не будет импортировать все модули пакета Sound.Effects, а только имена, явным образом определенные в инициализационном файле ‘__init__.py’ (включая явно импортированные в нем модули). Кроме того, в текущую область видимости попадут модули пакета, явно загруженные предыдущими инструкциями import, например:

import Sound.Effects.echo import Sound.Effects.surround from Sound.Effects import *

В приведенном примере, модули echo и surround импортируются в текущее пространство имен, потому что они уже определены в пакете Sound.Effects на момент выполнения инструкции from ... import.

Заметим, что импортирование всех имен, определенных в модуле или пакете, обычно приводит к засорению пространства имен и, как результат, к возможным конфликтам. (Некоторые модули специально спроектированы таким образом, чтобы экспортировать только имена, следующие определенному шаблону.) Кроме того, при этом глобальные переменные модуля становятся доступными только для чтения — при попытке присвоить такой переменной новое значение Вы создадите новую (локальную) переменную с таким же именем. А все изменения, внесенные в глобальные переменные модуля после его инициализации, не будут видны за его пределами.

6.6. Пакеты

67

Мы рекомендуем стараться использовать запись ‘from package import specific_module’, за исключением случаев, когда необходимо использовать модули с одинаковыми именами из разных пакетов.

6.6.2Связи между модулями пакета

Часто возникает необходимость в связях между модулями одного пакета. Например, модуль surround может использовать модуль echo. В самом деле, подобные связи распространены настолько, что инструкция import сначала просматривает содержимое пакета, в который входит содержащий эту инструкцию модуль, и только потом в путях поиска модулей. Таким образом, модуль surround может просто использовать ‘import echo’ или ‘from echo import echofilter’.

Когда пакеты разделены на подпакеты (пакет Sound в примере), нет краткой записи для ссылок между ответвлениями пакета — нужно использовать полное имя. Например, если модуль Sound.Filters.vocoder должен использовать модуль echo пакета

Sound.Effects, нужно использовать ‘from Sound.Effects import echo’.

68

Глава 7

Ввод/вывод

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

7.1Форматированный вывод

До сих пор мы использовали два способа вывода: вывод значений выражений в интерактивном режиме и с помощью инструкции print (третий способ — метод объектовфайлов write()).

Часто возникает желание иметь больший контроль над форматированием вывода, чем просто выводить значения, разделенные пробелом. Конечно, Вы можете сами обрабатывать строки: с помощью операций среза и объединения можно создать любое расположение, какое только Вы сможете представить. Строки имеют методы, позволяющие дополнять их пробелами до необходимой ширины колонки1. Другой путь — использовать оператор % со строкой в качестве левого аргумента. Оператор % интерпретирует строку справа как строку формата в стиле функции sprintf() в C, которую нужно применить к правому аргументу, и возвращает строку с результатом форматирования.

Безусловно, остается еще один вопрос: как получить строковое представление для значений различного типа? К счастью, Python предоставляет возможность преобразовывать значение любого типа в строку: с помощью функции str(). Фактически язык предоставляет две функции для получения строкового представления — repr() (тот же эффект можно получить просто заключив выражение в обратные кавычки: ‘expr‘) и str(). Первый способ, например, используется интерпретатором для вывода значений выражений в интерактивном режиме, второй — для вывода аргументов инструкцией print. Функция str() по возможности возвращает представление, наиболее пригодное для вывода, а функция repr() — для ввода выражения в интерактивном режиме. Приведем несколько примеров:

>>> x = 10 * 3.14

1Эти методы строк появились в версии 1.6 языка Python. В предыдущих версия они доступны в виде функций, определенных в модуле string.

7.1. Форматированный вывод

69

Число 31:4 не может быть точно представлено в двоичном виде, поэтому:

>>> x 31.399999999999999

Однако функция str() выведет число с разумной точностью:

>>>y = 200*200

>>>s = ’ъОБЮЕОЙЕ x ТБЧОП ’ + str(x) + \

...

’,

ЪОБЮЕОЙЕ y ТБЧОП ’ + str(y) + ’...’

>>>

print s

 

ъОБЮЕОЙЕ x

ТБЧОП 31.4, ЪОБЮЕОЙЕ y ТБЧОП 40000...

Длинные целые числа записываются в языке Python с суффиксом ‘L’. Начиная с версии 1.6, функция str() его не выводит:

>>>repr(1000L)

’1000L’

>>>str(1000L)

’1000’

Строковое представление можно получить и для других типов:

>>>p = [x, y]

>>>ps = repr(p)

>>>ps

’[31.399999999999999, 40000]’

>>> ‘x, y, (’spam’, ’eggs’)‘ "(31.399999999999999, 40000, (’spam’, ’eggs’))"

Функция repr() (или ‘‘) добавляет кавычки и записывает спецсимволы с помощью управляющих последовательностей:

>>>hello = ’hello, world\n’

>>>print hello

hello, world

>>>hellos = ‘hello‘

>>>print hellos ’hello, world\012’

Выведем таблицу квадратов и кубов двумя описанными способами:

70

 

Глава 7. Ввод/вывод

>>>

for

x in range(1, 11):

...

 

print str(x).rjust(2), str(x*x).rjust(3),

...

 

# пВТБФЙФЕ ЧОЙНБОЙЕ ОБ ЪБЧЕТЫБАЭХА ЪБРСФХА

...

 

print str(x*x*x).rjust(4)

...

 

 

1

1

1

2

4

8

3

9

27

4

16

64

5

25

125

6

36

216

7

49

343

8

64

512

9

81

729

10

100

1000

>>>

for

x in range(1,11):

...

 

print ’%2d %3d %4d’ % (x, x*x, x*x*x)

...

 

 

1

1

1

2

4

8

3

9

27

4

16

64

5

25

125

6

36

216

7

49

343

8

64

512

9

81

729

10

100

1000

(Обратите внимание на то, что один пробел между колонками был добавлен инструкцией print.)

Этот пример демонстрирует использование метода строк rjust(), который выравнивает строку вправо в поле заданной ширины, дополняя ее слева пробелами. Аналогично действуют методы ljust() и center(). Они не выводят ничего — просто возвращают новую строку. Если исходная строка слишком длинная, она не обрезается, а возвращается в неизменном виде: обычно лучше внести беспорядок в расположение колонок, чем вывести неверное значение. (Если Вы действительно хотите ее обрезать, воспользуйтесь операцией среза: ‘s.ljust(n)[0:n]’.)

Также может быть полезна функция zfill(), определенная в модуле string, которая дополняет слева нулями строку с числом, корректно обрабатывая знаки плюс и минус:

>>>import string

>>>string.zfill(’12’, 5) ’00012’