Главная страница

Учебник Python 3.1. Учебник Python 3. Учебник Python 1 Материал из Викиучебника. Оглавление


Скачать 1.85 Mb.
НазваниеУчебник Python 1 Материал из Викиучебника. Оглавление
АнкорУчебник Python 3.1.pdf
Дата05.04.2017
Размер1.85 Mb.
Формат файлаpdf
Имя файлаУчебник Python 3.1.pdf
ТипУчебник
#4516
страница3 из 13
1   2   3   4   5   6   7   8   9   ...   13
Операторы
break
и
continue
, а также условие
else
в циклах
Оператор break прерывает выполнение самого ближайшего вложенного цикла for или while
(по аналогии с языком C).
Оператор continue
, также заимствованный из C, продолжает выполнение цикла со следующей итерации.
Операторы циклов могут иметь ветвь else
. Она исполняется, когда цикл выполнил перебор до конца (в случае for
) или когда условие становится ложным (в случае while
), но не в тех случаях, когда цикл прерывается по break
. Это поведение иллюстрируется следующим примером, в котором производится поиск простых чисел:
>>>
for
n
in
range
(
2
,
10
):
for
x
in
range
(
2
,
n):
if
n % x
==
0
:
print
(n
,
'равно'
,
x
,
'*'
,
n//x)
break
else
:
# циклу не удалось найти множитель
print
(n
,
'- простое число'
)
2
- простое число
3
- простое число
4
равно
2
*
2 5
- простое число
6
равно
2
*
3 7
- простое число
8
равно
2
*
4 9
равно
3
*
3
Оператор
pass
Оператор pass не делает ничего. Он может использоваться когда синтаксически требуется присутствие оператора, но от программы не требуется действий. Например:
>>>
while
True
:
pass
# Ожидание прерывания c клавиатуры (Ctrl+C) в режиме занятости
Этот оператор часто используется для создания минималистичных классов, к примеру исключений (exceptions), или для игнорирования нежелательных исключений:
23

Учебник Python 3.1: Материал из Викиучебника.
>>>
class
ParserError(
Exception
):
pass
>>>
try
:
import
audioop
except
ImportError
:
pass
Другой вариант: pass может применяться в качестве заглушки для тела функции или условия при создании нового кода, позволяя вам сохранить абстрактный взгляд на вещи. С другой стороны, оператор pass игнорируется без каких-либо сигналов и лучшим выбором было бы породить исключение
NotImplementedError
:
>>>
def
initlog(*args):
raise
NotImplementedError
# Открыть файл для логгинга, если он ещё не
открыт
if
not
logfp:
raise
NotImplementedError
# Настроить заглушку для логгинга
raise
NotImplementedError
(
'Обработчик инициализации лога вызовов'
)
Если бы здесь использовались операторы pass
, а позже вы бы запускали тесты, они могли бы упасть без указания причины. Использование
NotImplementedError принуждает этот код породить исключение, сообщая вам конкретное место, где присутствует незавершённый код. Обратите внимание на два способа порождения исключений. Первый способ, без сообщения, но сопровождаемый комментарием, позволяет вам оставить комментарий когда вы будете подменять выброс исключения рабочим кодом, который, в свою очередь, в идеале, будет хорошим описанием блока кода, для которого исключение предназначалось заглушкой. Однако, передача сообщения вместе с исключением, как в третьем примере, обуславливает более насыщенный информацией вывод при отслеживании ошибки.
Определение функций
Мы можем создать функцию, которая выводит числа Фибоначчи до некоторого предела:
>>>
def
fib(n):
# вывести числа Фибоначчи меньшие (вплоть до) n
"""Выводит ряд Фибоначчи, ограниченный n."""
... a
,
b
=
0
,
1
while
b
<
n:
print
(b
,
end
=
' '
)
... a
,
b
=
b
,
a+b
print
(b)
>>>
# Теперь вызовем определенную нами функцию:
... fib(
2000
)
1 1
2 3
5 8
13 21 34 55 89 144 233 377 610 987 1597
Зарезервированное слово def предваряет определение функции. За ним должны следовать имя функции и заключённый в скобки список формальных параметров.
Выражения, формирующие тело функции, начинаются со следующей строки и должны иметь отступ.
Первым выражением в теле функции может быть строковой литерал — этот литерал является строкой документации функции, или док-строкой (docstring). (Больше информации одок-строках вы найдёте в разделе
Строки документации
) Существуют инструменты, которые используют док-строки для того, чтобы сгенерировать печатную
24

Учебник Python 3.1: Материал из Викиучебника.
или онлайн-документацию или чтобы позволить пользователю перемещаться по коду интерактивно; добавление строк документации в ваш код - это хорошая практика, постарайтесь к ней привыкнуть.
Исполнение функции приводит к созданию новой таблицы символов
[16]
, использующейся для хранения локальных переменных функции. Если быть более точными, все присваивания переменных в функции сохраняют значение в локальной таблице символов; при обнаружении ссылки на переменную, в первую очередь просматривается локальная таблица символов, затем локальная таблица символов для окружающих функций, затем глобальная таблица символов и, наконец, таблица встроенных имён. Таким образом, глобальным переменным невозможно прямо присвоить значения внутри функций (если они конечно не упомянуты в операторе global
) несмотря на то, что ссылки на них могут использоваться.
Фактические параметры при вызове функции помещаются в локальную таблицу символов вызванной функции; в результате аргументы передаются через вызов по значению (call by value) (где значение - это всегда ссылка (reference) на объект, а не значение его самого)
[17]
. Если одна функция вызывает другую — то для этого вызова создается новая локальная таблица символов.
При определении функции её имя также помещается в текущую таблицу символов. Тип значения, связанного с именем функции, распознается интерпретатором как функция, определённая пользователем (user-defined function). Само значение может быть присвоено другому имени, которое затем может также использоваться в качестве функции. Эта система работает в виде основного механизма переименования:
>>>
fib
<
function fib at 10042ed0
>
>>>
f
=
fib
>>>
f(
100
)
1 1
2 3
5 8
13 21 34 55 89
Если вы использовали в работе другие языки программирования, вы можете возразить, что fib
— это не функция, а процедура, поскольку не возвращает никакого значения. На самом деле, даже функции без ключевого слова return возвращают значение, хотя и более скучное. Такое значение именуется
None
(это встроенное имя). Вывод значения
None обычно подавляется в интерактивном режиме интерпретатора, если оно оказывается единственным значением, которое нужно вывести. Вы можете проследить за этим процессом, если действительно хотите, используя функцию print()
:
>>>
fib(
0
)
>>>
print
(fib(
0
))
None
Довольно легко написать функцию, которая возвращает список чисел из ряда Фибоначчи, вместо того, чтобы выводить их:
>>>
def
fib2(n):
# вернуть числа Фибоначчи меньшие (вплоть до) n
"""Возвращает список чисел ряда Фибоначчи, ограниченный n."""
... result
=
[]
... a
,
b
=
0
,
1
while
b
<
n:
... result.append(b)
# см. ниже
... a
,
b
=
b
,
a+b
return
result
25

Учебник Python 3.1: Материал из Викиучебника.
>>>
f100
=
fib2(
100
)
# вызываем
>>>
f100
# выводим результат
[
1
,
1
,
2
,
3
,
5
,
8
,
13
,
21
,
34
,
55
,
89
]
И на этот раз пример демонстрирует некоторые новые возможности Python:

Оператор return завершает выполнение функции, возвращая некоторое значение.
Оператор return без аргумента возвращает
None
. Достижение конца функции также возвращает
None

Выражение result.append(b)
вызывает метод append объекта-списка result
Метод — это функция, которая "принадлежит" объекту и указывается через выражение вида obj.methodname
, где obj
— некоторый объект (может быть выражением), а methodname
— имя метода, присущий объекту данного типа.
Различные типы определяют различные методы. Методы разных типов могут иметь одинаковые имена, не вызывая неопределённостей. (Позже в этом учебнике будет рассмотрено как определять собственные типы объектов и методы, используя классы.) Метод append()
, показанный в примере, определён для объектов типа список. Он добавляет в конец списка новый элемент. В данном примере это действие эквивалентно выражению result = result + [b]
, но более эффективно.
Подробнее об определении функций
Также есть возможность определять функции с переменным количеством параметров. Для этого существует три формы, которые также можно использовать совместно.
Значения аргументов по умолчанию
Наиболее полезной формой является задание значений по умолчанию для одного или более параметров. Таким образом создаётся функция, которая может быть вызвана с меньшим количеством параметров, чем в её определении: при этом неуказанные при вызове параметры примут данные в определении функции значения. Например
[18]
:
def
ask_ok(prompt
,
retries
=
4
,
complaint
=
'Yes or no, please!'
):
while
True
:
ok
=
input
(prompt)
if
ok
in
(
'y'
,
'yeah'
,
'yes'
,
'yep'
):
return
True
if
ok
in
(
'n'
,
'no'
,
'nop'
,
'nope'
):
return
False retries
=
retries -
1
if
retries
<
0
:
raise
IOError
(
'refusenik user'
)
print
(complaint)
Эта функция может быть вызвана, например, так: ask_ok('Do you really want to quit?')
или так: ask_ok('OK to overwrite the file?', 2)
Этот пример также знакомит вас с зарезервированным словом in
. Посредством его можно проверить, содержит ли последовательность определённое значение или нет.
Значения по умолчанию вычисляются в месте определения функции, в определяющей области, поэтому код i
=
5
def
f(arg
=
i):
print
(arg)
i
=
6
f()
26

Учебник Python 3.1: Материал из Викиучебника.
выведет 5.
Важное предупреждение: Значение по умолчанию вычисляется лишь единожды. Это особенно важно помнить, когда значением по умолчанию является изменяемый объект, такой как список, словарь (dictionary) или экземпляры большинства классов. Например, следующая функция накапливает переданные ей параметры:
def
f(a
,
L
=
[]):
L.append(a)
return
L
print
(f(
1
))
print
(f(
2
))
print
(f(
3
))
Она выведет
[
1
]
[
1
,
2
]
[
1
,
2
,
3
]
Если вы не хотите, чтобы значение по умолчанию распределялось между последовательными вызовами, вместо предыдущего варианта вы можете использовать такую идиому:
def
f(a
,
L
=
None
):
if
L
is
None
:
L
=
[]
L.append(a)
return
L
Именованные параметры
[19]
Функции также могут быть вызваны с использованием именованных параметров (keyword arguments) в форме "имя = значение". Например, нижеприведённая функция
[20]
:
def
parrot(voltage
,
state
=
'a stiff'
,
action
=
'voom'
,
type
=
'Norwegian Blue'
):
print
(
"-- This parrot wouldn't"
,
action
,
end
=
' '
)
print
(
"if you put"
,
voltage
,
"volts through it."
)
print
(
"-- Lovely plumage, the"
,
type
)
print
(
"-- It's"
,
state
,
"!"
)
могла бы быть вызвана любым из следующих способов
[21]
:
parrot(
1000
)
parrot(action
=
'VOOOOOM'
,
voltage
=
1000000
)
parrot(
'a thousand'
,
state
=
'pushing up the daisies'
)
parrot(
'a million'
,
'bereft of life'
,
'jump'
)
а эти случаи оказались бы неверными
[22]
:
parrot()
# пропущен требуемый аргумент
parrot(voltage
=
5.0
,
'dead'
)
# позиционный параметр вслед за именованным
parrot(
110
,
voltage
=
220
)
# повторное значение параметра
parrot(actor
=
'John Cleese'
)
# неизвестное имя параметра
В общем случае, список параметров должен содержать любое количество позиционных
(positional) параметров, за которыми может следовать любое количество именованных, и при этом имена аргументов выбираются из формальных параметров. Неважно, имеет формальный параметр значение по умолчанию или нет. Ни один из аргументов не может получать значение более чем один раз — имена формальных параметров, совпадающие с именами позиционных параметров, не могут использоваться в качестве именующих в
27

Учебник Python 3.1: Материал из Викиучебника.
одном и том же вызове
[23]
. Вот пример, завершающийся неудачей по причине описанного ограничения:
>>>
def
function(a):
pass
>>>
function(
0
,
a
=
0
)
Traceback (most recent call last):
File
""
,
line
1
,
in
?
TypeError
: function() got multiple values
for
keyword argument
'a'
Если в определении функции присутствует завершающий параметр в виде **имя, он получит в качестве значения словарь (подробнее в разделе

-
Справочника
Типы
— отображения словари
), содержащий все именованные параметры и их значения, исключая те, которые соответствуют формальным параметрам. Можно совместить эту особенность с поддержкой формального параметра в формате *имя (описывается в следующем подразделе), который получает кортеж (tuple), содержащий все позиционные параметры, следующие за списком формальных параметров. (параметр в формате *имя должен описываться перед параметром в формате **имя.) Например, если мы определим такую функцию
[24]
:
def
cheeseshop(kind
,
*arguments
,
**keywords):
print
(
"-- Do you have any"
,
kind
,
"?"
)
print
(
"-- I'm sorry, we're all out of"
,
kind)
for
arg
in
arguments:
print
(arg)
print
(
"-"
*
40
)
keys
=
sorted
(keywords.keys())
for
kw
in
keys:
print
(kw
,
":"
,
keywords[kw])
то её можно будет вызвать так
[25]
:
cheeseshop(
'Limburger'
,
"It's very runny, sir."
,
"It's really very, VERY runny, sir."
,
client
=
"John Cleese"
,
shopkeeper
=
"Michael Palin"
,
sketch
=
"Cheese Shop Sketch"
)
и она, конечно же, выведет
[26]
:
-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
---------------------------------------- client : John Cleese shopkeeper : Michael Palin sketch : Cheese Shop Sketch
Обратите внимание, что список имён (ключей) именованных параметров (
keys
) создается посредством сортировки содержимого списка ключей keys()
словаря keywords
; если бы этого не было сделано, порядок вывода параметров был бы произволен.
Списки параметров произвольной длины
Наконец, наиболее редко используется возможность указания того, что функция может быть вызвана с произвольным числом аргументов. При этом сами параметры будут
28

Учебник Python 3.1: Материал из Викиучебника.
обёрнуты в кортеж (см. раздел
Кортежи
). Переменное количество параметров могут предварять ноль или более обычных.
def
write_multiple_items(
file
,
separator
,
*args):
file
.write(separator.join(args))
Обычно параметры неизвестного заранее количества (variadic) указываются последними в списке формальных параметров, поскольку включают в себя все остальные переданные в функцию параметры. Все формальные параметры, которые следуют за параметром
*args
, должны быть только именованными, то есть, они могут быть заданы только по имени (в отличие от позиционных параметров).
>>>
def
concat(*args
,
sep
=
"/"
):
return
sep.join(args)
>>>
concat(
"earth"
,
"mars"
,
"venus"
)
'earth/mars/venus'
>>>
concat(
"earth"
,
"mars"
,
"venus"
,
sep
=
"."
)
'earth.mars.venus'
Распаковка списков параметров
Обратная ситуация возникает когда параметры уже содержатся в списке или в кортеже, но должны быть распакованы для вызова функции, требующей отдельных позиционных параметров. Например, встроенная функция range()
ожидает отдельные параметры start и stop соответственно. Если они не доступны раздельно, для распаковки аргументов из списка или кортежа в вызове функции используйте *-синтаксис:
>>>
list
(
range
(
3
,
6
))
# обычный вызов с отдельными параметрами
[
3
,
4
,
5
]
>>>
args
=
[
3
,
6
]
>>>
list
(
range
(*args))
# вызов с распакованными из списка параметрами
[
3
,
4
,
5
]
Схожим способом, словари могут получать именованные параметры через **- синтаксис
[27]
:
>>>
def
parrot(voltage
,
state
=
'a stiff'
,
action
=
'voom'
):
print
(
"-- This parrot wouldn't"
,
action
,
end
=
' '
)
1   2   3   4   5   6   7   8   9   ...   13


написать администратору сайта