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

Python

.pdf
Скачиваний:
63
Добавлен:
22.03.2016
Размер:
1.59 Mб
Скачать

• Передать список при вызове функции как набор аргументов можно, приписав к обозначению списка спереди звездочку

Пример:

def func(*args):

print(args)

func(1, 2, 3, 4, 'abc') # (1, 2, 3, 4, 'abc')

args - это кортеж из всех переданных аргументов функции, и с переменной можно работать так же, как и с кортежем.

Произвольное число именованных аргументов:

Обозначается двумя звездочками перед аргументом - **kwargs

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

Передать словарь при вызове функции как набор именованных аргументов можно, приписав две звездочки перед обозначением словаря. Например, так: **kwargs

Пример:

def func(**kwargs):

print(kwargs)

func(a=1, b=2, c=3, d='abc') # {'a': 1, 'b': 2, 'c': 3, 'd': 'abc'}

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

Комбинирование обычные аргументы, * и **:

def func(a, *pargs, **kwargs):

print(a, pargs, kwargs)

func(1, 2, 3, x=1, y=2) # 1 (2, 3) {'y': 2, 'x': 1}

Использование * и ** в вызовах функции:

• Форма * в вызове функций распаковывает, а не создает коллекцию аргументов.

def func(a, b, c, d):

print(a, b, c, d)

args = (1, 2)

args += (3, 4)

func(*args) # 1 2 3 4

• Форма ** в вызове функций распаковывает словари пар ключ/ значение в отдельные аргументы, которые передаются по ключу.

def func(a, b, c, d):

40

print(a, b, c, d)

args = {'a': 1, 'b': 2, 'c': 3}

args['d'] = 4

func(**args) # 1 2 3 4

Комбинирование:

def func(a, b, c, d):

print(a, b, c, d)

func(*(1, 2), **{'d': 4, 'c': 4}) # 1 2 4 4

func(1, *(2, 3), **{'d': 4}) # 1 2 3 4

func(1, c=3, *(2,), **{'d': 4}) # 1 2 3 4

func(1, *(2, 3), d=4) # 1 2 3 4

func(1, *(2,), c=3, **{'d':4}) # 1 2 3 4

Правила, определяющие порядок следования:

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

def func(a, *b, c):

print(a, b, c)

func(1, 2, c=3) # 1 (2,) 3

func(a=1, c=3) # 1 () 3

func(1, 2, 3)

# TypeError: kwonly() needs keyword-only argument c

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

Def func(a, *, b, c):

print(a, b, c)

func(1, c=3, b=2) # 1 2 3

func(c=3, b=2, a=1) # 1 2 3

func(1, 2, 3)

# TypeError: func() takes exactly 1 positional argument (3 given)

func(1)

# TypeError: func() needs keyword-only argument b

41

Так же, аргументы, которые могут передаваться только по именам, в заголовке функции должны предшествовать форме **args представления списка именованных аргументов произвольной длины и следовать за формой *args представления списка позиционных аргументов произвольной длины, когда присутствуют обе формы.

def func1(a, *b, **d, c=6):

print(a, b, c, d)

# Только именованные аргументы должны предшествовать **!

SyntaxError: invalid syntax

def func2(a, *b, c=6, **d):

print(a, b, c, d) # Коллекции аргументов в заголовке

func2(1, 2, 3, x=4, y=5) # Используется значение по умолчанию

# 1 (2, 3) 6 {'y': 5, 'x': 4}

def func3(a, c=6, *b, **d):

print(a, b, c, d) # c не является только именованным аргументом!

func3(1, 2, 3, x=4) # 1 (3,) 2 {'x': 4}

Всякий раз, когда именованный аргумент появляется перед формой *args, он интерпретируется как

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

42

ГЛАВА 4

Модули

Модули в языке Python – самые крупные организационные программные единицы, которые вмещают в себя программный код и данные, готовые для многократного использования. Если говорить более точно, модули в языке Python обычно соответствуют файлам программ (или расширениям, написанным на других языках программирования, таких как C, Java или C#). Каждый файл – это отдельный модуль, и модули могут импортировать другие модули для доступа к именам, которые в них определены.

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

import - позволяет клиентам (импортерам) получать модуль целиком

from - позволяет клиентам получать определенные имена из модуля

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

организации компонентов в систему автономных пакетов переменных, известных как пространства имен. Все имена, определяемые на верхнем уровне модуля, становятся атрибутами объекта импортируемого модуля. Операция импорта предоставляет доступ к именам в глобальной области видимости модуля.

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

С точки зрения теории модули играют как минимум три роли:

Повторное использование программного кода

Разделение системы пространств имен

Реализация служб или данных для совместного пользования

РАЗДЕЛ 1

Импортирование

модулей

Импортирование в языке Python - операция, которая выполняет следующие действия, когда программа впервые импортирует заданный файл:

1. Поиск файла модуля.

Прежде всего, интерпретатор должен определить местонахождение файла модуля, указанного в инструкции import. Фактически допускается указывать лишь простые имена – путь к каталогу и расширение файла должны быть опущены, потому что для поиска файла, соответствующего имени, указанному в инструкции import, интерпретатор использует стандартный путь поиска модулей (вместо записи в виде, например, import c:\ dir1\b.py, инструкция записывается просто – import b).

2. Компиляция в байт-код (если это необходимо).

После того как в пути поиска модулей будет найден файл, соответствующий имени в инструкции import, интерпретатор компилирует его в байт-код, если это необходимо. Интерпретатор проверяет время создания файла и пропускает этап компиляции исходного программного кода, если файл с байт-кодом .pyc не

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

3. Запуск программного кода модуля, чтобы создать объекты, которые он определяет.

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

44

результат работы инструкций print на верхнем уровне модуля. Инструкции def просто определяют объекты для последующего использования.

Любой заданный модуль по умолчанию импортируется только один раз за все время работы программы. Все последующие операции импорта того же модуля пропускают эти действия и просто выбирают уже находящийся в памяти объект модуля. Технически это обеспечивается за счет того, что интерпретатор сохраняет информацию о загруженных модулях в словаре с именем sys.modules и проверяет его при выполнении каждой операции импортирования.

Путь поиска модулей

В общих чертах пути поиска модулей в языке Python выбираются из объединенных данных следующих основных источников (некоторые из них предопределены, а некоторые можно настроить):

• Домашний каталог программы.

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

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

• Содержимое переменной окружения PYTHONPATH (если таковая определена).

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

• Каталоги стандартной библиотеки.

45

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

• Содержимое любых файлов с расширением .pht (если таковые имеются).

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

В конечном итоге объединение этих четырех компонентов составляет sys.path – список строк с именами каталогов. Первый и третий компоненты пути поиска определяются автоматически, но так как интерпретатор при поиске использует данные всех этих компонентов, от первого до последнего, то второй и четвертый компоненты можно использовать для расширения пути поиска, включая в него свои собственные каталоги с исходными текстами.

Настройка пути поиска

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

платформы. Например, в Windows можно воспользоваться ярлыком Система (System) в панели управления, чтобы записать в переменную PYTHONPATH список каталогов, разделенных точкой с запятой: c:\pycode\utilities;d:\pycode\package1. Или создать текстовый файл с именем C:\Python30\pydirs.pth,

который выглядит примерно так: c:\pycode\utilities d:\pycode\package1.

Автоматическое изменение пути поиска

Это описание пути поиска модулей является верным, но достаточно общим – точная конфигурация пути поиска зависит от типа платформы и версии Python. В зависимости от используемой платформы в путь поиска модулей автоматически могут добавляться дополнительные каталоги. Например, в путь поиска вслед за каталогами из переменной окружения PYTHONPATH и перед каталогами стандартной библиотеки интерпретатор может добавлять текущий рабочий каталог – каталог, откуда была запущена программа. Когда программа запускается из командной строки, текущий рабочий каталог может не совпадать с домашним каталогом, где находится главный файл программы (то есть с каталогом, где находится программа). Так как от запуска к запуску программы текущий рабочий каталог может изменяться, при обычных условиях рабочий каталог не должен иметь значения для операций импорта.

Список sys.path

46

Чтобы увидеть, как выглядит путь поиска модулей на платформе, нужно проверить содержимое встроенного списка sys.path. Этот список строк с именами каталогов представляет собой фактический путь поиска, используемый интерпретатором, – при выполнении операций импорта Python просматривает каждый каталог из списка, слева направо. Интерпретатор создает sys.path во время запуска программы. В результате получается список строк с именами каталогов, которые просматриваются интерпретатором при импортировании новых файлов. Представление языком Python этого списка имеет два основных полезных результата. Вопервых, он обеспечивает возможность проверить настройки пути поиска, которые вы выполнили. Вовторых, можно обеспечить сценариям возможность самостоятельно задавать свои пути поиска.

Выбор файла модуля

Расширения имен файлов (например, .py) преднамеренно опущены в инструкции import. Интерпретатор выбирает первый найденный в пути поиска файл, который соответствует указанному имени. Например, инструкция import b могла бы загрузить:

Файл с исходным текстом, имеющий имя b.py.

Файл с байт-кодом, имеющий имя b.pyc.

Содержимое каталога b при импортировании пакета.

Скомпилированный модуль расширения, написанный, как правило, на языке C или C++ и скомпонованный в виде динамической библиотеки (например, b.so в Linux и b.dll или b.pyd в Cygwin и в Windows).

Скомпилированный встроенный модуль, написанный на языке C и статически скомпонованный с интерпретатором Python.

Файл ZIP-архива с компонентом, который автоматически извлекается при импорте.

Образ памяти для фиксированных двоичных исполняемых файлов.

Класс Java в версии Jython.

Компонент .NET в версии IronPython.

Если в различных каталогах имеются файлы b.py и b.so, интерпретатор всегда будет загружать тот, что будет найден в каталоге, который располагается раньше (левее) в пути поиска модулей.

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

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

47

как загрузка файлов из архивов, расшифровывание и так далее.

Импортирование и области видимости

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

48

РАЗДЕЛ 2

Импорт From

Одним из способов вызова функций из модуля является импорт from. С помощью него мы можем явно импортировать одну или сразу все функции модуля. Функции импортируются в локальное пространство имён и, поэтому, становятся доступны для прямого вызова.

Пример вызова одной или нескольких функций

Импорт одной функции

 

from module import func

# из модуля module мы явно

импортируем функцию func

 

func()

# вызываем функцию без префикса

модуля перед ней

 

 

Импорт всех функций модуля

from module import *

# из модуля module мы

импортируем все функции

 

func1()

 

 

func2()

# вызываем функции без префикса

модуля перед ними Импорт функции с заменой имени

from module import func as my_func

# из модуля

 

module мы явно импортируем функцию

 

func

 

 

 

 

 

#

и

переименовываем

её

my_func()

# вызываем функцию уже под новым

 

именем

 

 

 

 

# без префикса модуля перед ней

49

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]